Skip to content

Commit

Permalink
ThreadSwitcher 新增 SynchronizationContextThreadSwitcher
Browse files Browse the repository at this point in the history
  • Loading branch information
wherewhere committed Mar 18, 2024
1 parent 32dc2a0 commit 220d2a0
Showing 1 changed file with 50 additions and 15 deletions.
65 changes: 50 additions & 15 deletions CoreAppUWP/Common/ThreadSwitcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,34 @@ public interface IThreadSwitcher : INotifyCompletion
IThreadSwitcher GetAwaiter();
}

/// <summary>
/// The interface of helper type for switch thread.
/// </summary>
/// <typeparam name="T">The type of the result of <see cref="GetAwaiter"/>.</typeparam>
public interface IThreadSwitcher<T> : IThreadSwitcher
{
/// <summary>
/// Gets an awaiter used to await <typeparamref name="T"/>.
/// </summary>
/// <returns>A <typeparamref name="T"/> awaiter instance.</returns>
new T GetAwaiter();
}

/// <summary>
/// A helper type for switch thread by <see cref="CoreDispatcher"/>. This type is not intended to be used directly from your code.
/// </summary>
/// <param name="Dispatcher">A <see cref="CoreDispatcher"/> whose foreground thread to switch execution to.</param>
/// <param name="Priority">Specifies the priority for event dispatch.</param>
[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<CoreDispatcherThreadSwitcher>
{
/// <inheritdoc/>
public bool IsCompleted => Dispatcher?.HasThreadAccess != false;

/// <inheritdoc/>
public void GetResult() { }

/// <summary>
/// Gets an awaiter used to await this <see cref="CoreDispatcherThreadSwitcher"/>.
/// </summary>
/// <returns>An awaiter instance.</returns>
/// <inheritdoc/>
public CoreDispatcherThreadSwitcher GetAwaiter() => this;

/// <inheritdoc/>
Expand All @@ -66,7 +76,7 @@ public interface IThreadSwitcher : INotifyCompletion
/// <param name="Dispatcher">A <see cref="DispatcherQueue"/> whose foreground thread to switch execution to.</param>
/// <param name="Priority">Specifies the priority for event dispatch.</param>
[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<DispatcherQueueThreadSwitcher>
{
/// <inheritdoc/>
public bool IsCompleted => Dispatcher is not DispatcherQueue dispatcher
Expand All @@ -75,10 +85,7 @@ public interface IThreadSwitcher : INotifyCompletion
/// <inheritdoc/>
public void GetResult() { }

/// <summary>
/// Gets an awaiter used to await this <see cref="DispatcherQueueThreadSwitcher"/>.
/// </summary>
/// <returns>An awaiter instance.</returns>
/// <inheritdoc/>
public DispatcherQueueThreadSwitcher GetAwaiter() => this;

/// <inheritdoc/>
Expand All @@ -88,23 +95,44 @@ public interface IThreadSwitcher : INotifyCompletion
public void OnCompleted(Action continuation) => _ = Dispatcher.TryEnqueue(Priority, () => continuation());
}

/// <summary>
/// A helper type for switch thread by <see cref="SynchronizationContext"/>. This type is not intended to be used directly from your code.
/// </summary>
/// <param name="Context">A <see cref="SynchronizationContext"/> whose foreground thread to switch execution to.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public readonly record struct SynchronizationContextThreadSwitcher(SynchronizationContext Context) : IThreadSwitcher<SynchronizationContextThreadSwitcher>
{
/// <inheritdoc/>
public bool IsCompleted => Context is not SynchronizationContext context
|| SynchronizationContext.Current == context;

/// <inheritdoc/>
public void GetResult() { }

/// <inheritdoc/>
public SynchronizationContextThreadSwitcher GetAwaiter() => this;

/// <inheritdoc/>
IThreadSwitcher IThreadSwitcher.GetAwaiter() => this;

/// <inheritdoc/>
public void OnCompleted(Action continuation) => Context.Post(_ => continuation(), null);
}

/// <summary>
/// A helper type for switch thread by <see cref="ThreadPool"/>. This type is not intended to be used directly from your code.
/// </summary>
/// <param name="Priority">Specifies the priority for event dispatch.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public readonly record struct ThreadPoolThreadSwitcher(WorkItemPriority Priority = WorkItemPriority.Normal) : IThreadSwitcher
public readonly record struct ThreadPoolThreadSwitcher(WorkItemPriority Priority = WorkItemPriority.Normal) : IThreadSwitcher<ThreadPoolThreadSwitcher>
{
/// <inheritdoc/>
public bool IsCompleted => SynchronizationContext.Current == null;

/// <inheritdoc/>
public void GetResult() { }

/// <summary>
/// Gets an awaiter used to await this <see cref="ThreadPoolThreadSwitcher"/>.
/// </summary>
/// <returns>An awaiter instance.</returns>
/// <inheritdoc/>
public ThreadPoolThreadSwitcher GetAwaiter() => this;

/// <inheritdoc/>
Expand Down Expand Up @@ -141,6 +169,13 @@ public static class ThreadSwitcher
/// <returns>An object that you can <see langword="await"/>.</returns>
public static CoreDispatcherThreadSwitcher ResumeForegroundAsync(this CoreDispatcher dispatcher, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal) => new(dispatcher, priority);

/// <summary>
/// A helper function—for use within a coroutine—that you can <see langword="await"/> to switch execution to a specific foreground thread.
/// </summary>
/// <param name="context">A <see cref="SynchronizationContext"/> whose foreground thread to switch execution to.</param>
/// <returns>An object that you can <see langword="await"/>.</returns>
public static SynchronizationContextThreadSwitcher ResumeForegroundAsync(this SynchronizationContext context) => new(context);

/// <summary>
/// A helper function—for use within a coroutine—that returns control to the caller, and then immediately resumes execution on a thread pool thread.
/// </summary>
Expand Down

0 comments on commit 220d2a0

Please sign in to comment.