Skip to content

Commit 8464f8e

Browse files
committed
Fixed dispatcher for Xaml Islands. leveraging DispatcherQueueHelper in favor of DispatcherHelper.
1 parent 9c95639 commit 8464f8e

25 files changed

+904
-116
lines changed

GazeInputTest/App.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
using Microsoft.Toolkit.Uwp.Input.GazeInteraction;
65
using System;
6+
using Microsoft.Toolkit.Uwp.Input.GazeInteraction;
77
using Windows.ApplicationModel;
88
using Windows.ApplicationModel.Activation;
99
using Windows.UI.Xaml;

GazeInputTest/MainPage.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
using Microsoft.Toolkit.Uwp.Input.GazeInteraction;
65
using System;
6+
using Microsoft.Toolkit.Uwp.Input.GazeInteraction;
77
using Windows.ApplicationModel.Core;
88
using Windows.UI.Core;
99
using Windows.UI.ViewManagement;

Microsoft.Toolkit.Uwp.Connectivity/BluetoothLEHelper/BluetoothLEHelper.cs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
using System.Linq;
99
using System.Threading;
1010
using System.Threading.Tasks;
11-
using Windows.ApplicationModel.Core;
11+
using Microsoft.Toolkit.Uwp.Helpers;
1212
using Windows.Devices.Bluetooth;
1313
using Windows.Devices.Bluetooth.Advertisement;
1414
using Windows.Devices.Enumeration;
1515
using Windows.Foundation.Metadata;
16-
using Windows.UI.Core;
16+
using Windows.System;
1717

1818
namespace Microsoft.Toolkit.Uwp.Connectivity
1919
{
@@ -59,11 +59,15 @@ public class BluetoothLEHelper
5959
/// </summary>
6060
private BluetoothAdapter _adapter;
6161

62+
private DispatcherQueue _dispatcherQueue;
63+
6264
/// <summary>
6365
/// Prevents a default instance of the <see cref="BluetoothLEHelper" /> class from being created.
6466
/// </summary>
6567
private BluetoothLEHelper()
6668
{
69+
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
70+
6771
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
6872
Init();
6973
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
@@ -201,8 +205,7 @@ private async Task Init()
201205
/// <param name="args">The advertisement.</param>
202206
private async void AdvertisementWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
203207
{
204-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
205-
CoreDispatcherPriority.Normal,
208+
await _dispatcherQueue.ExecuteOnUIThreadAsync(
206209
() =>
207210
{
208211
if (_readerWriterLockSlim.TryEnterReadLock(TimeSpan.FromSeconds(1)))
@@ -217,7 +220,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
217220

218221
_readerWriterLockSlim.ExitReadLock();
219222
}
220-
});
223+
}, DispatcherQueuePriority.Normal);
221224
}
222225

223226
/// <summary>
@@ -286,19 +289,20 @@ private async void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformation
286289
// Protect against race condition if the task runs after the app stopped the deviceWatcher.
287290
if (sender == _deviceWatcher)
288291
{
289-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
290-
{
291-
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
292+
await _dispatcherQueue.ExecuteOnUIThreadAsync(
293+
() =>
292294
{
293-
var device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);
294-
BluetoothLeDevices.Remove(device);
295+
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
296+
{
297+
var device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);
298+
BluetoothLeDevices.Remove(device);
295299

296-
var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);
297-
_unusedDevices?.Remove(unusedDevice);
300+
var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);
301+
_unusedDevices?.Remove(unusedDevice);
298302

299-
_readerWriterLockSlim.ExitWriteLock();
300-
}
301-
});
303+
_readerWriterLockSlim.ExitWriteLock();
304+
}
305+
}, DispatcherQueuePriority.Normal);
302306
}
303307
}
304308

@@ -327,16 +331,15 @@ private async Task AddDeviceToList(DeviceInformation deviceInfo)
327331
// Make sure device name isn't blank or already present in the list.
328332
if (!string.IsNullOrEmpty(deviceInfo?.Name))
329333
{
330-
var device = new ObservableBluetoothLEDevice(deviceInfo);
334+
var device = new ObservableBluetoothLEDevice(deviceInfo, _dispatcherQueue);
331335
var connectable = (device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable") &&
332336
(bool)device.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"]) ||
333337
(device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.IsConnected") &&
334338
(bool)device.DeviceInfo.Properties["System.Devices.Aep.IsConnected"]);
335339

336340
if (connectable)
337341
{
338-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
339-
CoreDispatcherPriority.Normal,
342+
await _dispatcherQueue.ExecuteOnUIThreadAsync(
340343
() =>
341344
{
342345
if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
@@ -348,7 +351,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
348351

349352
_readerWriterLockSlim.ExitWriteLock();
350353
}
351-
});
354+
}, DispatcherQueuePriority.Normal);
352355

353356
return;
354357
}

Microsoft.Toolkit.Uwp.Connectivity/BluetoothLEHelper/ObservableBluetoothLEDevice.cs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
using System.Runtime.CompilerServices;
1212
using System.Threading;
1313
using System.Threading.Tasks;
14-
using Windows.ApplicationModel.Core;
14+
using Microsoft.Toolkit.Uwp.Helpers;
1515
using Windows.Devices.Bluetooth;
1616
using Windows.Devices.Bluetooth.GenericAttributeProfile;
1717
using Windows.Devices.Enumeration;
18+
using Windows.System;
1819
using Windows.UI.Core;
1920
using Windows.UI.Xaml.Media.Imaging;
2021

@@ -134,17 +135,22 @@ public int Compare(object x, object y)
134135
private ObservableCollection<ObservableGattDeviceService> _services =
135136
new ObservableCollection<ObservableGattDeviceService>();
136137

138+
private DispatcherQueue _dispatcherQueue;
139+
137140
/// <summary>
138141
/// Initializes a new instance of the <see cref="ObservableBluetoothLEDevice"/> class.
139142
/// </summary>
140143
/// <param name="deviceInfo">The device information.</param>
141-
public ObservableBluetoothLEDevice(DeviceInformation deviceInfo)
144+
/// <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>
145+
public ObservableBluetoothLEDevice(DeviceInformation deviceInfo, DispatcherQueue dispatcherQueue = null)
142146
{
143147
DeviceInfo = deviceInfo;
144148
Name = DeviceInfo.Name;
145149

146150
IsPaired = DeviceInfo.Pairing.IsPaired;
147151

152+
_dispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
153+
148154
LoadGlyph();
149155

150156
this.PropertyChanged += ObservableBluetoothLEDevice_PropertyChanged;
@@ -395,7 +401,8 @@ private void ObservableBluetoothLEDevice_PropertyChanged(object sender, Property
395401
/// <exception cref="Exception">Thorws Exception when no permission to access device</exception>
396402
public async Task ConnectAsync()
397403
{
398-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
404+
await _dispatcherQueue.ExecuteOnUIThreadAsync(
405+
async () =>
399406
{
400407
if (BluetoothLEDevice == null)
401408
{
@@ -442,7 +449,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio
442449
throw new Exception(_result.ProtocolError.GetErrorString());
443450
}
444451
}
445-
});
452+
}, DispatcherQueuePriority.Normal);
446453
}
447454

448455
/// <summary>
@@ -468,8 +475,7 @@ public async Task DoInAppPairingAsync()
468475
/// <returns>The task of the update.</returns>
469476
public async Task UpdateAsync(DeviceInformationUpdate deviceUpdate)
470477
{
471-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
472-
CoreDispatcherPriority.Normal,
478+
await _dispatcherQueue.ExecuteOnUIThreadAsync(
473479
() =>
474480
{
475481
DeviceInfo.Update(deviceUpdate);
@@ -479,7 +485,7 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
479485

480486
LoadGlyph();
481487
OnPropertyChanged("DeviceInfo");
482-
});
488+
}, DispatcherQueuePriority.Normal);
483489
}
484490

485491
/// <summary>
@@ -512,9 +518,7 @@ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName
512518
/// <param name="args">The arguments.</param>
513519
private async void BluetoothLEDevice_NameChanged(BluetoothLEDevice sender, object args)
514520
{
515-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
516-
CoreDispatcherPriority.Normal,
517-
() => { Name = BluetoothLEDevice.Name; });
521+
await _dispatcherQueue.ExecuteOnUIThreadAsync(() => { Name = BluetoothLEDevice.Name; }, DispatcherQueuePriority.Normal);
518522
}
519523

520524
/// <summary>
@@ -524,29 +528,27 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
524528
/// <param name="args">The arguments.</param>
525529
private async void BluetoothLEDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
526530
{
527-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
528-
CoreDispatcherPriority.Normal,
531+
await _dispatcherQueue.ExecuteOnUIThreadAsync(
529532
() =>
530533
{
531534
IsPaired = DeviceInfo.Pairing.IsPaired;
532535
IsConnected = BluetoothLEDevice.ConnectionStatus == BluetoothConnectionStatus.Connected;
533-
});
536+
}, DispatcherQueuePriority.Normal);
534537
}
535538

536539
/// <summary>
537540
/// Load the glyph for this device
538541
/// </summary>
539542
private async void LoadGlyph()
540543
{
541-
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
542-
CoreDispatcherPriority.Normal,
544+
await _dispatcherQueue.ExecuteOnUIThreadAsync(
543545
async () =>
544546
{
545547
var deviceThumbnail = await DeviceInfo.GetGlyphThumbnailAsync();
546548
var glyphBitmapImage = new BitmapImage();
547549
await glyphBitmapImage.SetSourceAsync(deviceThumbnail);
548550
Glyph = glyphBitmapImage;
549-
});
551+
}, DispatcherQueuePriority.Normal);
550552
}
551553
}
552554
}

Microsoft.Toolkit.Uwp.Connectivity/BluetoothLEHelper/ObservableGattCharacteristics.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
using System.Linq;
88
using System.Runtime.CompilerServices;
99
using System.Threading.Tasks;
10+
using Microsoft.Toolkit.Uwp.Helpers;
1011
using Windows.Devices.Bluetooth;
1112
using Windows.Devices.Bluetooth.GenericAttributeProfile;
1213
using Windows.Security.Cryptography;
1314
using Windows.Storage.Streams;
15+
using Windows.System;
1416

1517
namespace Microsoft.Toolkit.Uwp.Connectivity
1618
{
@@ -110,13 +112,17 @@ public enum DisplayTypes
110112
/// </summary>
111113
private string _value;
112114

115+
private DispatcherQueue _dispatcherQueue;
116+
113117
/// <summary>
114118
/// Initializes a new instance of the <see cref="ObservableGattCharacteristics"/> class.
115119
/// </summary>
116120
/// <param name="characteristic">The characteristic.</param>
117121
/// <param name="parent">The parent.</param>
118122
public ObservableGattCharacteristics(GattCharacteristic characteristic, ObservableGattDeviceService parent)
119123
{
124+
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
125+
120126
Characteristic = characteristic;
121127
Parent = parent;
122128
Name = GattUuidsService.ConvertUuidToName(Characteristic.Uuid);
@@ -459,9 +465,7 @@ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName
459465
/// <param name="args">The <see cref="GattValueChangedEventArgs"/> instance containing the event data.</param>
460466
private async void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
461467
{
462-
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
463-
Windows.UI.Core.CoreDispatcherPriority.Normal,
464-
() => { SetValue(args.CharacteristicValue); });
468+
await _dispatcherQueue.ExecuteOnUIThreadAsync(() => { SetValue(args.CharacteristicValue); }, DispatcherQueuePriority.Normal);
465469
}
466470

467471
/// <summary>

Microsoft.Toolkit.Uwp.SampleApp/Controls/CodeRenderer.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,14 @@ protected override void OnApplyTemplate()
8787

8888
private void RenderDocument()
8989
{
90-
_codeView?.Blocks?.Clear();
91-
_formatter = new RichTextBlockFormatter(_theme);
92-
_formatter.FormatRichTextBlock(_displayedText, _language, _codeView);
93-
_rendered = true;
90+
if (_codeView != null)
91+
{
92+
_codeView.Blocks?.Clear();
93+
_formatter = new RichTextBlockFormatter(_theme);
94+
95+
_formatter.FormatRichTextBlock(_displayedText, _language, _codeView);
96+
_rendered = true;
97+
}
9498
}
9599

96100
private void CopyButton_Click(object sender, RoutedEventArgs e)

Microsoft.Toolkit.Uwp.SampleApp/Shell.xaml.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.Toolkit.Uwp.Helpers;
77
using Microsoft.Toolkit.Uwp.SampleApp.Pages;
88
using Microsoft.Toolkit.Uwp.UI.Extensions;
9+
using Windows.System;
910
using Windows.UI.Xaml;
1011
using Windows.UI.Xaml.Controls;
1112
using Windows.UI.Xaml.Media.Animation;
@@ -127,7 +128,7 @@ private void SamplePickerGridView_Loaded(object sender, Windows.UI.Xaml.RoutedEv
127128
{
128129
if (s is UIElement samplePicker && samplePicker.Visibility == Visibility.Visible)
129130
{
130-
DispatcherHelper.ExecuteOnUIThreadAsync(() => SamplePickerGridView.Focus(FocusState.Keyboard));
131+
DispatcherQueue.GetForCurrentThread().ExecuteOnUIThreadAsync(() => SamplePickerGridView.Focus(FocusState.Keyboard));
131132
}
132133
});
133134
}

Microsoft.Toolkit.Uwp.UI/Cache/ImageCache.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Microsoft.Toolkit.Uwp.Helpers;
1111
using Windows.Storage;
1212
using Windows.Storage.Streams;
13+
using Windows.System;
1314
using Windows.UI.Xaml.Media.Imaging;
1415

1516
namespace Microsoft.Toolkit.Uwp.UI
@@ -34,11 +35,14 @@ public class ImageCache : CacheBase<BitmapImage>
3435
/// </summary>
3536
public static ImageCache Instance => _instance ?? (_instance = new ImageCache());
3637

38+
private DispatcherQueue _dispatcherQueue;
39+
3740
/// <summary>
3841
/// Initializes a new instance of the <see cref="ImageCache"/> class.
3942
/// </summary>
4043
public ImageCache()
4144
{
45+
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
4246
_extendedPropertyNames.Add(DateAccessedProperty);
4347
}
4448

@@ -55,7 +59,7 @@ protected override async Task<BitmapImage> InitializeTypeAsync(Stream stream, Li
5559
throw new FileNotFoundException();
5660
}
5761

58-
return await DispatcherHelper.ExecuteOnUIThreadAsync(async () =>
62+
return await _dispatcherQueue.ExecuteOnUIThreadAsync(async () =>
5963
{
6064
BitmapImage image = new BitmapImage();
6165

0 commit comments

Comments
 (0)