Created
August 29, 2018 23:05
-
-
Save MysteryDash/bc2e48ca1a0f28fa211ad84a98da2f5c to your computer and use it in GitHub Desktop.
Provides the caller with means to remove and restore the current SynchronizationContext in an async method.
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; | |
/// <summary> | |
/// Provides the caller with means to remove and restore the current <see cref="SynchronizationContext"/> in an async method. | |
/// </summary> | |
public class SynchronizationContextRemover : INotifyCompletion | |
{ | |
private SynchronizationContextRemover() | |
{ | |
} | |
/// <summary> | |
/// An awaitable <see cref="SynchronizationContext"/> remover. | |
/// The current <see cref="SynchronizationContext"/> will be restored at the end of the caller's execution. | |
/// </summary> | |
public static SynchronizationContextRemover AwaitableRemover => new SynchronizationContextRemover(); | |
/// <summary> | |
/// A disposable <see cref="SynchronizationContext"/> remover, meant to be used with the <see langword="using"/> statement. | |
/// The current <see cref="SynchronizationContext"/> will be restored upon disposal of this instance. | |
/// </summary> | |
public static IDisposable DisposableRemover => new DisposableContextRemover(); | |
public bool IsCompleted => SynchronizationContext.Current == null; | |
public void OnCompleted(Action continuation) | |
{ | |
var previousContext = SynchronizationContext.Current; | |
try | |
{ | |
SynchronizationContext.SetSynchronizationContext(null); | |
continuation(); | |
} | |
finally | |
{ | |
SynchronizationContext.SetSynchronizationContext(previousContext); | |
} | |
} | |
public SynchronizationContextRemover GetAwaiter() | |
{ | |
return this; | |
} | |
public void GetResult() | |
{ | |
} | |
private class DisposableContextRemover : IDisposable | |
{ | |
private readonly SynchronizationContext _previousContext; | |
internal DisposableContextRemover() | |
{ | |
_previousContext = SynchronizationContext.Current; | |
SynchronizationContext.SetSynchronizationContext(null); | |
} | |
public void Dispose() | |
{ | |
SynchronizationContext.SetSynchronizationContext(_previousContext); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment