Skip to content

Instantly share code, notes, and snippets.

@dtaylor-530
Last active October 19, 2022 13:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dtaylor-530/4485d290d994dd97b3bcf8bae51782de to your computer and use it in GitHub Desktop.
Save dtaylor-530/4485d290d994dd97b3bcf8bae51782de to your computer and use it in GitHub Desktop.
switching to UI thread
public async void btnStart_Click(object sender, RoutedEventArgs e)
{
var syncContext = SynchronizationContext.Current;
lblStatus.Text = "Working...";
// non blocking call
var data = await GetDataFromRemoteServerAsync().ConfigureAwait(false);
// blocking call, but runs on a worker thread
DoSomeCpuBoundWorkWithTheData(data);
// switch back to the UI thread
await syncContext;
lblStatus.Text = "Done";
}
/// <summary>
/// <a href="https://thomaslevesque.com/2015/11/11/explicitly-switch-to-the-ui-thread-in-an-async-method/"/></a>
/// </summary>
public struct SynchronizationContextAwaiter : INotifyCompletion
{
private static readonly SendOrPostCallback _postCallback = state => ((Action)state)();
private readonly SynchronizationContext _context;
public SynchronizationContextAwaiter(SynchronizationContext context)
{
_context = context;
}
public bool IsCompleted => _context == SynchronizationContext.Current;
public void OnCompleted(Action continuation) => _context.Post(_postCallback, continuation);
public void GetResult() { }
}
public static class SynchronizationContextHelper
{
public static SynchronizationContextAwaiter GetAwaiter(this SynchronizationContext context)
{
return new SynchronizationContextAwaiter(context);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment