From a82f877e7ba5a30cb29f1a889a3c9a12e3a6f3db Mon Sep 17 00:00:00 2001 From: wherewhere Date: Mon, 11 Mar 2024 16:22:02 +0800 Subject: [PATCH] =?UTF-8?q?ThreadSwitcher=20=E6=96=B0=E5=A2=9E=20Synchroni?= =?UTF-8?q?zationContextThreadSwitcher?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CoreAppUWP/Common/ThreadSwitcher.cs | 85 +++++++++++++++++++---------- 1 file changed, 57 insertions(+), 28 deletions(-) diff --git a/CoreAppUWP/Common/ThreadSwitcher.cs b/CoreAppUWP/Common/ThreadSwitcher.cs index 3e661c7..5137d28 100644 --- a/CoreAppUWP/Common/ThreadSwitcher.cs +++ b/CoreAppUWP/Common/ThreadSwitcher.cs @@ -17,12 +17,12 @@ public interface IThreadSwitcher : INotifyCompletion /// /// Gets a value that indicates whether the asynchronous operation has completed. /// - bool IsCompleted => true; + bool IsCompleted { get; } /// /// Ends the await on the completed task. /// - void GetResult() { } + void GetResult(); /// /// Gets an awaiter used to await this . @@ -31,33 +31,41 @@ void GetResult() { } IThreadSwitcher GetAwaiter(); } + /// + /// The interface of helper type for switch thread. + /// + /// The type of the result of . + public interface IThreadSwitcher : IThreadSwitcher + { + /// + /// Gets an awaiter used to await . + /// + /// An awaiter instance. + new T GetAwaiter(); + } + /// /// A helper type for switch thread by . This type is not intended to be used directly from your code. /// /// A whose foreground thread to switch execution to. /// Specifies the priority for event dispatch. [EditorBrowsable(EditorBrowsableState.Never)] - public readonly record struct CoreDispatcherThreadSwitcher(CoreDispatcher Dispatcher, CoreDispatcherPriority Priority = CoreDispatcherPriority.Normal) : IThreadSwitcher + public readonly record struct CoreDispatcherThreadSwitcher(CoreDispatcher Dispatcher, CoreDispatcherPriority Priority = CoreDispatcherPriority.Normal) : IThreadSwitcher { - /// - /// Gets a value that indicates whether the asynchronous operation has completed. - /// + /// public bool IsCompleted => Dispatcher?.HasThreadAccess != false; /// public void GetResult() { } - /// - /// Gets an awaiter used to await this . - /// - /// An awaiter instance. + /// public CoreDispatcherThreadSwitcher GetAwaiter() => this; /// IThreadSwitcher IThreadSwitcher.GetAwaiter() => this; /// - public void OnCompleted(Action continuation) => _ = Dispatcher?.RunAsync(Priority, () => continuation()); + public void OnCompleted(Action continuation) => _ = Dispatcher.RunAsync(Priority, () => continuation()); } /// @@ -66,27 +74,46 @@ public void GetResult() { } /// A whose foreground thread to switch execution to. /// Specifies the priority for event dispatch. [EditorBrowsable(EditorBrowsableState.Never)] - public readonly record struct DispatcherQueueThreadSwitcher(DispatcherQueue Dispatcher, DispatcherQueuePriority Priority = DispatcherQueuePriority.Normal) : IThreadSwitcher + public readonly record struct DispatcherQueueThreadSwitcher(DispatcherQueue Dispatcher, DispatcherQueuePriority Priority = DispatcherQueuePriority.Normal) : IThreadSwitcher { - /// - /// Gets a value that indicates whether the asynchronous operation has completed. - /// + /// public bool IsCompleted => Dispatcher?.HasThreadAccess != false; /// public void GetResult() { } - /// - /// Gets an awaiter used to await this . - /// - /// An awaiter instance. + /// public DispatcherQueueThreadSwitcher GetAwaiter() => this; /// IThreadSwitcher IThreadSwitcher.GetAwaiter() => this; /// - public void OnCompleted(Action continuation) => _ = Dispatcher?.TryEnqueue(Priority, () => continuation()); + public void OnCompleted(Action continuation) => _ = Dispatcher.TryEnqueue(Priority, () => continuation()); + } + + /// + /// A helper type for switch thread by . This type is not intended to be used directly from your code. + /// + /// A whose foreground thread to switch execution to. + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly record struct SynchronizationContextThreadSwitcher(SynchronizationContext Context) : IThreadSwitcher + { + /// + public bool IsCompleted => Context is not SynchronizationContext context + || SynchronizationContext.Current == context; + + /// + public void GetResult() { } + + /// + public SynchronizationContextThreadSwitcher GetAwaiter() => this; + + /// + IThreadSwitcher IThreadSwitcher.GetAwaiter() => this; + + /// + public void OnCompleted(Action continuation) => Context.Post(_ => continuation(), null); } /// @@ -94,20 +121,15 @@ public void GetResult() { } /// /// Specifies the priority for event dispatch. [EditorBrowsable(EditorBrowsableState.Never)] - public readonly record struct ThreadPoolThreadSwitcher(WorkItemPriority Priority = WorkItemPriority.Normal) : IThreadSwitcher + public readonly record struct ThreadPoolThreadSwitcher(WorkItemPriority Priority = WorkItemPriority.Normal) : IThreadSwitcher { - /// - /// Gets a value that indicates whether the asynchronous operation has completed. - /// + /// public bool IsCompleted => SynchronizationContext.Current == null; /// public void GetResult() { } - /// - /// Gets an awaiter used to await this . - /// - /// An awaiter instance. + /// public ThreadPoolThreadSwitcher GetAwaiter() => this; /// @@ -138,6 +160,13 @@ public static class ThreadSwitcher /// An object that you can . public static CoreDispatcherThreadSwitcher ResumeForegroundAsync(this CoreDispatcher dispatcher, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal) => new(dispatcher, priority); + /// + /// A helper function—for use within a coroutine—that you can to switch execution to a specific foreground thread. + /// + /// A whose foreground thread to switch execution to. + /// An object that you can . + public static SynchronizationContextThreadSwitcher ResumeForegroundAsync(this SynchronizationContext context) => new(context); + /// /// A helper function—for use within a coroutine—that returns control to the caller, and then immediately resumes execution on a thread pool thread. ///