|
@@ -6,8 +6,9 @@
|
|
|
using System.Reactive.Disposables;
|
|
|
using System.Runtime.ExceptionServices;
|
|
|
using System.Threading;
|
|
|
+using Windows.System;
|
|
|
using Windows.UI.Core;
|
|
|
-#if !NET5_0_WINDOWS10_0_19041
|
|
|
+#if HAS_OS_XAML
|
|
|
using Windows.UI.Xaml;
|
|
|
#endif
|
|
|
namespace System.Reactive.Concurrency
|
|
@@ -29,7 +30,7 @@ namespace System.Reactive.Concurrency
|
|
|
public CoreDispatcherScheduler(CoreDispatcher dispatcher)
|
|
|
{
|
|
|
Dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
|
|
|
- Priority = CoreDispatcherPriority.Normal;
|
|
|
+ Priority = CoreDispatcherPriority.Normal;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -66,6 +67,8 @@ namespace System.Reactive.Concurrency
|
|
|
/// </summary>
|
|
|
public CoreDispatcher Dispatcher { get; }
|
|
|
|
|
|
+ private DispatcherQueue? _dispatcherQueue;
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Gets the priority at which work is scheduled.
|
|
|
/// </summary>
|
|
@@ -109,10 +112,10 @@ namespace System.Reactive.Concurrency
|
|
|
// For scheduler implementation guidance rules, see TaskPoolScheduler.cs
|
|
|
// in System.Reactive.PlatformServices\Reactive\Concurrency.
|
|
|
//
|
|
|
- var timer = new DispatcherTimer
|
|
|
- {
|
|
|
- Interval = TimeSpan.Zero
|
|
|
- };
|
|
|
+
|
|
|
+ var timer = CreateDispatcherQueue().CreateTimer();
|
|
|
+ timer.Interval = TimeSpan.Zero;
|
|
|
+
|
|
|
timer.Tick += (o, e) =>
|
|
|
{
|
|
|
timer.Stop();
|
|
@@ -130,6 +133,28 @@ namespace System.Reactive.Concurrency
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ private DispatcherQueue CreateDispatcherQueue()
|
|
|
+ {
|
|
|
+ if(_dispatcherQueue != null)
|
|
|
+ {
|
|
|
+ return _dispatcherQueue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(Dispatcher.HasThreadAccess)
|
|
|
+ {
|
|
|
+ _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
|
|
+ return _dispatcherQueue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // We're on a different thread, get it from the right one
|
|
|
+ Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
|
|
|
+ {
|
|
|
+ _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
|
|
+ }).GetAwaiter().GetResult(); // This is a synchronous call and we need the result to proceed
|
|
|
+
|
|
|
+ return _dispatcherQueue!;
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Schedules an action to be executed after <paramref name="dueTime"/> on the dispatcher, using a <see cref="DispatcherTimer"/> object.
|
|
|
/// </summary>
|
|
@@ -159,7 +184,8 @@ namespace System.Reactive.Concurrency
|
|
|
{
|
|
|
var d = new MultipleAssignmentDisposable();
|
|
|
|
|
|
- var timer = new DispatcherTimer();
|
|
|
+
|
|
|
+ var timer = CreateDispatcherQueue().CreateTimer();
|
|
|
|
|
|
timer.Tick += (o, e) =>
|
|
|
{
|
|
@@ -220,7 +246,7 @@ namespace System.Reactive.Concurrency
|
|
|
throw new ArgumentNullException(nameof(action));
|
|
|
}
|
|
|
|
|
|
- var timer = new DispatcherTimer();
|
|
|
+ var timer = CreateDispatcherQueue().CreateTimer();
|
|
|
|
|
|
var state1 = state;
|
|
|
|