Created
December 6, 2016 18:05
-
-
Save GeorgeTsiokos/1c3f975357b9db4c32b7b73b3f9aede4 to your computer and use it in GitHub Desktop.
SynchronizationContextExtensions - Task<T> ExecuteAsync<T>
This file contains 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
public static class SynchronizationContextExtensions { | |
public static Task<T> ExecuteAsync<T> (this SynchronizationContext synchronizationContext, Func<T> factory, CancellationToken cancellationToken = default (CancellationToken)) { | |
var state = new State<T> (factory, | |
cancellationToken); | |
synchronizationContext.Post (ExecuteAsync<T>, | |
state); | |
return state.Task; | |
} | |
private static void ExecuteAsync<T> (object state) { | |
var asyncState = (State<T>)state; | |
var taskCompletionSource = asyncState.TaskCompletionSource; | |
var cancellationToken = asyncState.CancellationToken; | |
if (cancellationToken.IsCancellationRequested) { | |
taskCompletionSource.TrySetCanceled (cancellationToken); | |
return; | |
} | |
try { | |
var value = asyncState.Factory (); | |
taskCompletionSource.TrySetResult (value); | |
} | |
catch (Exception exception) { | |
taskCompletionSource.TrySetException (exception); | |
} | |
} | |
private sealed class State<T> { | |
public State (Func<T> factory, CancellationToken cancellationToken) { | |
CancellationToken = cancellationToken; | |
TaskCompletionSource = new TaskCompletionSource<T> (factory); | |
} | |
public CancellationToken CancellationToken { get; } | |
public TaskCompletionSource<T> TaskCompletionSource { get; } | |
public Task<T> Task => TaskCompletionSource.Task; | |
public Func<T> Factory => (Func<T>)Task.AsyncState; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment