Last active
April 11, 2024 06:53
-
-
Save DarkOoze/38748365e634c1f70ecb542faf61f8fa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.CompilerServices; | |
using System.Threading; | |
using System.Windows.Forms; | |
public static class TaskExtensions | |
{ | |
/// <summary> | |
/// Creates an awaitable task that asynchronously yields back to the current context of the control. | |
/// </summary> | |
/// <param name="control"></param> | |
/// <returns>A context that, when awaited, will asynchronously transition back into the | |
/// context of the control.</returns> | |
public static ControlYieldAwaitable Yield(this Control control) | |
{ | |
return new ControlYieldAwaitable(control); | |
} | |
public struct ControlYieldAwaitable | |
{ | |
private readonly Control control; | |
public ControlYieldAwaitable(Control control) | |
{ | |
this.control = control; | |
} | |
public YieldAwaiter GetAwaiter() | |
{ | |
return new YieldAwaiter(this.control); | |
} | |
public readonly struct YieldAwaiter : ICriticalNotifyCompletion, INotifyCompletion | |
{ | |
private readonly SynchronizationContext syncContext; | |
private static readonly SendOrPostCallback sendOrPostCallbackRunAction = RunAction; | |
public YieldAwaiter(Control control) | |
{ | |
this.syncContext = GetSynchronizationContext(control); | |
} | |
public bool IsCompleted => this.syncContext == SynchronizationContext.Current; | |
public void OnCompleted(Action continuation) | |
{ | |
this.syncContext.Post(sendOrPostCallbackRunAction, continuation); | |
} | |
public void UnsafeOnCompleted(Action continuation) | |
{ | |
this.syncContext.Post(sendOrPostCallbackRunAction, continuation); | |
} | |
public void GetResult() | |
{ | |
} | |
private static SynchronizationContext GetSynchronizationContext(Control control) | |
{ | |
if (control.InvokeRequired) | |
return (SynchronizationContext)control.Invoke(new Func<Control, SynchronizationContext>(GetSynchronizationContext), control); | |
return SynchronizationContext.Current; | |
} | |
private static void RunAction(object state) => ((Action)state).Invoke(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment