Changed all dispatcher queue fields to properties, so they can be set after the creation of their parents.
This commit is contained in:
Родитель
8464f8e526
Коммит
beafb0a8f7
|
@ -59,14 +59,18 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
/// </summary>
|
||||
private BluetoothAdapter _adapter;
|
||||
|
||||
private DispatcherQueue _dispatcherQueue;
|
||||
/// <summary>
|
||||
/// Gets or sets which DispatcherQueue is used to dispatch UI updates.
|
||||
/// </summary>
|
||||
public DispatcherQueue DispatcherQueue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="BluetoothLEHelper" /> class from being created.
|
||||
/// </summary>
|
||||
private BluetoothLEHelper()
|
||||
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates, or null if this is being called from the UI thread.</param>
|
||||
private BluetoothLEHelper(DispatcherQueue dispatcherQueue = null)
|
||||
{
|
||||
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
Init();
|
||||
|
@ -205,7 +209,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
/// <param name="args">The advertisement.</param>
|
||||
private async void AdvertisementWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
() =>
|
||||
{
|
||||
if (_readerWriterLockSlim.TryEnterReadLock(TimeSpan.FromSeconds(1)))
|
||||
|
@ -289,7 +293,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
// Protect against race condition if the task runs after the app stopped the deviceWatcher.
|
||||
if (sender == _deviceWatcher)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
() =>
|
||||
{
|
||||
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
|
||||
|
@ -331,7 +335,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
// Make sure device name isn't blank or already present in the list.
|
||||
if (!string.IsNullOrEmpty(deviceInfo?.Name))
|
||||
{
|
||||
var device = new ObservableBluetoothLEDevice(deviceInfo, _dispatcherQueue);
|
||||
var device = new ObservableBluetoothLEDevice(deviceInfo, DispatcherQueue);
|
||||
var connectable = (device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable") &&
|
||||
(bool)device.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"]) ||
|
||||
(device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.IsConnected") &&
|
||||
|
@ -339,7 +343,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
|
||||
if (connectable)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
() =>
|
||||
{
|
||||
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
|
||||
|
|
|
@ -135,7 +135,10 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
private ObservableCollection<ObservableGattDeviceService> _services =
|
||||
new ObservableCollection<ObservableGattDeviceService>();
|
||||
|
||||
private DispatcherQueue _dispatcherQueue;
|
||||
/// <summary>
|
||||
/// Gets or sets which DispatcherQueue is used to dispatch UI updates.
|
||||
/// </summary>
|
||||
public DispatcherQueue DispatcherQueue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ObservableBluetoothLEDevice"/> class.
|
||||
|
@ -149,7 +152,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
|
||||
IsPaired = DeviceInfo.Pairing.IsPaired;
|
||||
|
||||
_dispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
LoadGlyph();
|
||||
|
||||
|
@ -401,7 +404,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
/// <exception cref="Exception">Thorws Exception when no permission to access device</exception>
|
||||
public async Task ConnectAsync()
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
async () =>
|
||||
{
|
||||
if (BluetoothLEDevice == null)
|
||||
|
@ -475,7 +478,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
/// <returns>The task of the update.</returns>
|
||||
public async Task UpdateAsync(DeviceInformationUpdate deviceUpdate)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
() =>
|
||||
{
|
||||
DeviceInfo.Update(deviceUpdate);
|
||||
|
@ -518,7 +521,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
/// <param name="args">The arguments.</param>
|
||||
private async void BluetoothLEDevice_NameChanged(BluetoothLEDevice sender, object args)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(() => { Name = BluetoothLEDevice.Name; }, DispatcherQueuePriority.Normal);
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(() => { Name = BluetoothLEDevice.Name; }, DispatcherQueuePriority.Normal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -528,7 +531,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
/// <param name="args">The arguments.</param>
|
||||
private async void BluetoothLEDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
() =>
|
||||
{
|
||||
IsPaired = DeviceInfo.Pairing.IsPaired;
|
||||
|
@ -541,7 +544,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
/// </summary>
|
||||
private async void LoadGlyph()
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
async () =>
|
||||
{
|
||||
var deviceThumbnail = await DeviceInfo.GetGlyphThumbnailAsync();
|
||||
|
|
|
@ -112,16 +112,20 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
/// </summary>
|
||||
private string _value;
|
||||
|
||||
private DispatcherQueue _dispatcherQueue;
|
||||
/// <summary>
|
||||
/// Gets or sets which DispatcherQueue is used to dispatch UI updates.
|
||||
/// </summary>
|
||||
public DispatcherQueue DispatcherQueue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ObservableGattCharacteristics"/> class.
|
||||
/// </summary>
|
||||
/// <param name="characteristic">The characteristic.</param>
|
||||
/// <param name="parent">The parent.</param>
|
||||
public ObservableGattCharacteristics(GattCharacteristic characteristic, ObservableGattDeviceService parent)
|
||||
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates, or null if this is being called from the UI thread.</param>
|
||||
public ObservableGattCharacteristics(GattCharacteristic characteristic, ObservableGattDeviceService parent, DispatcherQueue dispatcherQueue = null)
|
||||
{
|
||||
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
Characteristic = characteristic;
|
||||
Parent = parent;
|
||||
|
@ -465,7 +469,7 @@ namespace Microsoft.Toolkit.Uwp.Connectivity
|
|||
/// <param name="args">The <see cref="GattValueChangedEventArgs"/> instance containing the event data.</param>
|
||||
private async void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(() => { SetValue(args.CharacteristicValue); }, DispatcherQueuePriority.Normal);
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(() => { SetValue(args.CharacteristicValue); }, DispatcherQueuePriority.Normal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -35,14 +35,18 @@ namespace Microsoft.Toolkit.Uwp.UI
|
|||
/// </summary>
|
||||
public static ImageCache Instance => _instance ?? (_instance = new ImageCache());
|
||||
|
||||
private DispatcherQueue _dispatcherQueue;
|
||||
/// <summary>
|
||||
/// Gets or sets which DispatcherQueue is used to dispatch UI updates.
|
||||
/// </summary>
|
||||
public DispatcherQueue DispatcherQueue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ImageCache"/> class.
|
||||
/// </summary>
|
||||
public ImageCache()
|
||||
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates, or null if this is being called from the UI thread.</param>
|
||||
public ImageCache(DispatcherQueue dispatcherQueue = null)
|
||||
{
|
||||
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
_extendedPropertyNames.Add(DateAccessedProperty);
|
||||
}
|
||||
|
||||
|
@ -59,7 +63,7 @@ namespace Microsoft.Toolkit.Uwp.UI
|
|||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
return await _dispatcherQueue.ExecuteOnUIThreadAsync(async () =>
|
||||
return await DispatcherQueue.ExecuteOnUIThreadAsync(async () =>
|
||||
{
|
||||
BitmapImage image = new BitmapImage();
|
||||
|
||||
|
|
|
@ -47,7 +47,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Helpers
|
|||
/// </summary>
|
||||
public bool IsHighContrast { get; set; }
|
||||
|
||||
private DispatcherQueue _dispatcherQueue;
|
||||
/// <summary>
|
||||
/// Gets or sets which DispatcherQueue is used to dispatch UI updates.
|
||||
/// </summary>
|
||||
public DispatcherQueue DispatcherQueue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An event that fires if the Theme changes.
|
||||
|
@ -60,12 +63,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Helpers
|
|||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ThemeListener"/> class.
|
||||
/// </summary>
|
||||
public ThemeListener()
|
||||
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates, or null if this is being called from the UI thread.</param>
|
||||
public ThemeListener(DispatcherQueue dispatcherQueue = null)
|
||||
{
|
||||
CurrentTheme = Application.Current.RequestedTheme;
|
||||
IsHighContrast = _accessible.HighContrast;
|
||||
|
||||
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
_accessible.HighContrastChanged += Accessible_HighContrastChanged;
|
||||
_settings.ColorValuesChanged += Settings_ColorValuesChanged;
|
||||
|
@ -90,9 +94,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Helpers
|
|||
await OnColorValuesChanged();
|
||||
}
|
||||
|
||||
internal async Task OnColorValuesChanged()
|
||||
internal Task OnColorValuesChanged()
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
return DispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
() =>
|
||||
{
|
||||
// TODO: This doesn't stop the multiple calls if we're in our faked 'White' HighContrast Mode below.
|
||||
|
|
|
@ -102,7 +102,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
|
||||
var taskCompletionSource = new TaskCompletionSource<T>();
|
||||
|
||||
_ = dispatcher.TryEnqueue(priority, () =>
|
||||
bool ok = dispatcher.TryEnqueue(priority, () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -159,7 +159,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
|
||||
var taskCompletionSource = new TaskCompletionSource<object>();
|
||||
|
||||
_ = dispatcher.TryEnqueue(priority, async () =>
|
||||
bool ok = dispatcher.TryEnqueue(priority, async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -222,7 +222,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
|
||||
var taskCompletionSource = new TaskCompletionSource<T>();
|
||||
|
||||
_ = dispatcher.TryEnqueue(priority, async () =>
|
||||
bool ok = dispatcher.TryEnqueue(priority, async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -96,16 +96,20 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
/// </summary>
|
||||
private PrintHelperOptions _defaultPrintHelperOptions;
|
||||
|
||||
private DispatcherQueue _dispatcherQueue;
|
||||
/// <summary>
|
||||
/// Gets or sets which DispatcherQueue is used to dispatch UI updates.
|
||||
/// </summary>
|
||||
public DispatcherQueue DispatcherQueue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PrintHelper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="canvasContainer">XAML panel used to attach printing canvas. Can be hidden in your UI with Opacity = 0 for instance</param>
|
||||
/// <param name="defaultPrintHelperOptions">Default settings for the print tasks</param>
|
||||
public PrintHelper(Panel canvasContainer, PrintHelperOptions defaultPrintHelperOptions = null)
|
||||
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates, or null if this is being called from the UI thread.</param>
|
||||
public PrintHelper(Panel canvasContainer, PrintHelperOptions defaultPrintHelperOptions = null, DispatcherQueue dispatcherQueue = null)
|
||||
{
|
||||
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
if (canvasContainer == null)
|
||||
{
|
||||
|
@ -201,7 +205,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
}
|
||||
|
||||
_printCanvas = null;
|
||||
_dispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
DispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
{
|
||||
_printDocument.Paginate -= CreatePrintPreviewPages;
|
||||
_printDocument.GetPreviewPage -= GetPrintPreviewPage;
|
||||
|
@ -225,7 +229,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
{
|
||||
if (!_directPrint)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
{
|
||||
_canvasContainer.Children.Remove(_printCanvas);
|
||||
_printCanvas.Children.Clear();
|
||||
|
@ -258,7 +262,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
printTask.Completed += async (s, args) =>
|
||||
{
|
||||
// Notify the user when the print operation fails.
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
async () =>
|
||||
{
|
||||
foreach (var element in _stateBags.Keys)
|
||||
|
@ -476,7 +480,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
// Save state
|
||||
if (!_stateBags.ContainsKey(element))
|
||||
{
|
||||
var stateBag = new PrintHelperStateBag(_dispatcherQueue);
|
||||
var stateBag = new PrintHelperStateBag(DispatcherQueue);
|
||||
stateBag.Capture(element);
|
||||
_stateBags.Add(element, stateBag);
|
||||
}
|
||||
|
@ -511,7 +515,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
element.Margin = new Thickness(marginWidth / 2, marginHeight / 2, marginWidth / 2, marginHeight / 2);
|
||||
page.Content = element;
|
||||
|
||||
return _dispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
return DispatcherQueue.ExecuteOnUIThreadAsync(
|
||||
() =>
|
||||
{
|
||||
// Add the (newly created) page to the print canvas which is part of the visual tree and force it to go
|
||||
|
@ -527,7 +531,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
|
||||
private Task ClearPageCache()
|
||||
{
|
||||
return _dispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
return DispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
{
|
||||
if (!_directPrint)
|
||||
{
|
||||
|
|
|
@ -25,15 +25,18 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
|
||||
private RemoteSystemWatcher _remoteSystemWatcher;
|
||||
|
||||
private DispatcherQueue _dispatcherQueue;
|
||||
/// <summary>
|
||||
/// Gets or sets which DispatcherQueue is used to dispatch UI updates.
|
||||
/// </summary>
|
||||
public DispatcherQueue DispatcherQueue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RemoteDeviceHelper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates for this BluetoothLE Device, or null if this is being called from the UI thread.</param>
|
||||
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates, or null if this is being called from the UI thread.</param>
|
||||
public RemoteDeviceHelper(DispatcherQueue dispatcherQueue = null)
|
||||
{
|
||||
_dispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
RemoteSystems = new ObservableCollection<RemoteSystem>();
|
||||
GenerateSystems();
|
||||
}
|
||||
|
@ -42,10 +45,10 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
/// Initializes a new instance of the <see cref="RemoteDeviceHelper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="filter">Initiate Enumeration with specific RemoteSysemKind with Filters</param>
|
||||
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates for this BluetoothLE Device, or null if this is being called from the UI thread.</param>
|
||||
/// <param name="dispatcherQueue">The DispatcherQueue that should be used to dispatch UI updates, or null if this is being called from the UI thread.</param>
|
||||
public RemoteDeviceHelper(List<IRemoteSystemFilter> filter, DispatcherQueue dispatcherQueue = null)
|
||||
{
|
||||
_dispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
|
||||
RemoteSystems = new ObservableCollection<RemoteSystem>();
|
||||
GenerateSystemsWithFilterAsync(filter);
|
||||
}
|
||||
|
@ -94,7 +97,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
|
||||
private async void RemoteSystemWatcher_RemoteSystemUpdated(RemoteSystemWatcher sender, RemoteSystemUpdatedEventArgs args)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
{
|
||||
RemoteSystems.Remove(RemoteSystems.First(a => a.Id == args.RemoteSystem.Id));
|
||||
RemoteSystems.Add(args.RemoteSystem);
|
||||
|
@ -103,7 +106,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
|
||||
private async void RemoteSystemWatcher_RemoteSystemRemoved(RemoteSystemWatcher sender, RemoteSystemRemovedEventArgs args)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
{
|
||||
RemoteSystems.Remove(RemoteSystems.First(a => a.Id == args.RemoteSystemId));
|
||||
});
|
||||
|
@ -111,7 +114,7 @@ namespace Microsoft.Toolkit.Uwp.Helpers
|
|||
|
||||
private async void RemoteSystemWatcher_RemoteSystemAdded(RemoteSystemWatcher sender, RemoteSystemAddedEventArgs args)
|
||||
{
|
||||
await _dispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
await DispatcherQueue.ExecuteOnUIThreadAsync(() =>
|
||||
{
|
||||
RemoteSystems.Add(args.RemoteSystem);
|
||||
});
|
||||
|
|
|
@ -7,17 +7,17 @@ using Windows.UI.Xaml.Hosting;
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Microsoft.Toolkit.Win32.UI.XamlHost;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Xaml;
|
||||
using System.Reflection;
|
||||
using Windows.System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace UnitTests.XamlIslands
|
||||
{
|
||||
class Program
|
||||
{
|
||||
private static IXamlMetadataContainer _metadataContainer;
|
||||
internal static CoreDispatcher _dispatcher;
|
||||
private static Task _task;
|
||||
internal static DispatcherQueue _dispatcher;
|
||||
|
||||
[STAThread]
|
||||
public static void Main()
|
||||
|
@ -29,36 +29,54 @@ namespace UnitTests.XamlIslands
|
|||
var frame = UWPTypeFactory.CreateXamlContentByType("Windows.UI.Xaml.Controls.Frame");
|
||||
xamlSource.Content = frame;
|
||||
|
||||
_dispatcher = xamlSource.Content.XamlRoot.Content.Dispatcher;
|
||||
_dispatcher = DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
_task = Task.Run(async () =>
|
||||
_dispatcher.TryEnqueue(DispatcherQueuePriority.Normal, async () =>
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
|
||||
{
|
||||
foreach (var testClass in typeof(XamlIslandsTest_ThemeListener_Threading).Assembly.GetTypes())
|
||||
{
|
||||
Attribute[] attributes = Attribute.GetCustomAttributes(testClass);
|
||||
TestResult testResult = default;
|
||||
|
||||
foreach (Attribute attribute in attributes)
|
||||
Stopwatch sw = new Stopwatch();
|
||||
|
||||
ConsoleWriteLineColor("--- Starting Tests Execution ---");
|
||||
|
||||
sw.Start();
|
||||
|
||||
foreach (var testClass in typeof(XamlIslandsTest_ThemeListener_Threading).Assembly.GetTypes())
|
||||
{
|
||||
Attribute[] attributes = Attribute.GetCustomAttributes(testClass);
|
||||
|
||||
foreach (Attribute attribute in attributes)
|
||||
{
|
||||
if (attribute is STATestClassAttribute || attribute is TestClassAttribute)
|
||||
{
|
||||
if (attribute is STATestClassAttribute || attribute is TestClassAttribute)
|
||||
{
|
||||
await RunTestsAsync(testClass);
|
||||
break;
|
||||
}
|
||||
var partialTestResult = await RunTestsAsync(testClass);
|
||||
testResult += partialTestResult;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_dispatcher.StopProcessEvents();
|
||||
Window.Current.CoreWindow.Close();
|
||||
});
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
|
||||
var color = testResult.Failed == 0 ? ConsoleColor.Green : ConsoleColor.Red;
|
||||
|
||||
ConsoleWriteLineColor($"--- Finished Tests Execution ({testResult.Passed}/{testResult.Count}) ---", color);
|
||||
ConsoleWriteLineColor($"--- Duration - {sw.Elapsed} ---");
|
||||
|
||||
Window.Current.CoreWindow.Close();
|
||||
System.Windows.Application.Current.Shutdown();
|
||||
});
|
||||
|
||||
_dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessUntilQuit);
|
||||
// This is just to have a Win32 message loop so the dispatcher processes it's events. This is not WPF or WinForms specific.
|
||||
var app = new System.Windows.Application();
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task RunTestsAsync(Type type)
|
||||
private static async Task<TestResult> RunTestsAsync(Type type)
|
||||
{
|
||||
int count = 0;
|
||||
int passed = 0;
|
||||
var initMethod = GetFirstMethod(type, typeof(TestInitializeAttribute));
|
||||
var cleanupMethod = GetFirstMethod(type, typeof(TestCleanupAttribute));
|
||||
|
||||
|
@ -70,6 +88,7 @@ namespace UnitTests.XamlIslands
|
|||
{
|
||||
if (attribute is STATestMethodAttribute || attribute is TestMethodAttribute)
|
||||
{
|
||||
count++;
|
||||
try
|
||||
{
|
||||
var instance = Activator.CreateInstance(type);
|
||||
|
@ -99,6 +118,7 @@ namespace UnitTests.XamlIslands
|
|||
}
|
||||
|
||||
TestPass(type, method);
|
||||
passed++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -108,19 +128,38 @@ namespace UnitTests.XamlIslands
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new TestResult(count, passed);
|
||||
}
|
||||
|
||||
struct TestResult
|
||||
{
|
||||
public int Count { get; }
|
||||
public int Passed { get; }
|
||||
public int Failed => Count - Passed;
|
||||
public TestResult(int count, int passed)
|
||||
{
|
||||
Count = count;
|
||||
Passed = passed;
|
||||
}
|
||||
|
||||
public static TestResult operator +(TestResult a, TestResult b) => new TestResult(a.Count + b.Count, a.Passed + b.Passed);
|
||||
}
|
||||
|
||||
private static void TestPass(Type type, MethodInfo method)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine($"{type.FullName}.{method.Name}\t - \tPASS");
|
||||
Console.ResetColor();
|
||||
ConsoleWriteLineColor($"{type.FullName}.{method.Name}\t - \tPASS", ConsoleColor.Green);
|
||||
}
|
||||
|
||||
private static void TestFail(Type type, MethodInfo method, Exception ex)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"{type.FullName}.{method.Name}\t - \tFAIL:{Environment.NewLine}{ex}");
|
||||
ConsoleWriteLineColor($"{type.FullName}.{method.Name}\t - \tFAIL:{Environment.NewLine}{ex}", ConsoleColor.Red);
|
||||
}
|
||||
|
||||
private static void ConsoleWriteLineColor(string message, ConsoleColor color = ConsoleColor.White)
|
||||
{
|
||||
Console.ForegroundColor = color;
|
||||
Console.WriteLine(message);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<UseWpf>true</UseWpf>
|
||||
<RuntimeIdentifiers>win-x86</RuntimeIdentifiers>
|
||||
<AssetTargetFallback>uap10.0.18362</AssetTargetFallback>
|
||||
<ApplicationManifest>UnitTests.XamlIslands.dll.manifest</ApplicationManifest>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<StartupObject>UnitTests.XamlIslands.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -27,11 +27,5 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Microsoft.Toolkit.Uwp.UI\Microsoft.Toolkit.Uwp.UI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="UnitTests.XamlIslands.dll.manifest">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC Manifest Options
|
||||
If you want to change the Windows User Account Control level replace the
|
||||
requestedExecutionLevel node with one of the following.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
Specifying requestedExecutionLevel element will disable file and registry virtualization.
|
||||
Remove this element if your application requires this virtualization for backwards
|
||||
compatibility.
|
||||
-->
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows Vista -->
|
||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||
|
||||
<!-- Windows 7 -->
|
||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
|
||||
|
||||
<!-- Windows 8 -->
|
||||
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
|
||||
|
||||
<!-- Windows 8.1 -->
|
||||
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
|
||||
<maxversiontested Id="10.0.18362.0"/>
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
|
||||
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
|
||||
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
|
||||
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
|
||||
<!--
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
-->
|
||||
|
||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||
<!--
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
</assembly>
|
|
@ -25,7 +25,7 @@ namespace UnitTests.XamlIslands
|
|||
_themeListener = new ThemeListener();
|
||||
_themeListener.ThemeChanged += (s) =>
|
||||
{
|
||||
_taskCompletionSource.SetResult(null);
|
||||
_taskCompletionSource.TrySetResult(null);
|
||||
};
|
||||
|
||||
Application.Current.RequestedTheme = ApplicationTheme.Dark;
|
||||
|
|
|
@ -4,18 +4,6 @@
|
|||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC Manifest Options
|
||||
If you want to change the Windows User Account Control level replace the
|
||||
requestedExecutionLevel node with one of the following.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
Specifying requestedExecutionLevel element will disable file and registry virtualization.
|
||||
Remove this element if your application requires this virtualization for backwards
|
||||
compatibility.
|
||||
-->
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
|
@ -23,55 +11,7 @@
|
|||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows Vista -->
|
||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||
|
||||
<!-- Windows 7 -->
|
||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
|
||||
|
||||
<!-- Windows 8 -->
|
||||
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
|
||||
|
||||
<!-- Windows 8.1 -->
|
||||
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
|
||||
<maxversiontested Id="10.0.18362.0"/>
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
|
||||
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
|
||||
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
|
||||
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
|
||||
<!--
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
-->
|
||||
|
||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||
<!--
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
</assembly>
|
||||
|
|
Загрузка…
Ссылка в новой задаче