public static async Task ConfigureTopologyAsync(this Link @this, Func<ILinkTopologyConfig, Task> configure, CancellationToken cancellationToken) { var completion = new TaskCompletionSource(); if (cancellationToken.IsCancellationRequested) { completion.TrySetCanceled(); await completion.Task; return; } using (@this.CreateTopologyConfigurator(configure, () => { completion.TrySetResultWithBackgroundContinuations(); return Task.FromResult((object) null); }, ex => { completion.TrySetExceptionWithBackgroundContinuations(ex); return Task.FromResult((object) null); })) { IDisposable registration = null; try { registration = cancellationToken.Register(() => { completion.TrySetCanceledWithBackgroundContinuations(); }); } catch (ObjectDisposedException) { // Cancellation source already disposed } if (cancellationToken.IsCancellationRequested) { completion.TrySetCanceledWithBackgroundContinuations(); } try { await completion.Task .ConfigureAwait(false); } finally { registration?.Dispose(); } } }
public void TrySetCanceledWithBackgroundContinuations_RunsOnAnotherThread() { AsyncContext.Run(async () => { var unitTestThreadId = Thread.CurrentThread.ManagedThreadId; int continuationThreadId = unitTestThreadId; var tcs = new TaskCompletionSource(); var continuation = tcs.Task.ContinueWith(_ => { continuationThreadId = Thread.CurrentThread.ManagedThreadId; }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); tcs.TrySetCanceledWithBackgroundContinuations(); await continuation; Assert.AreNotEqual(unitTestThreadId, continuationThreadId); }); }
public void TrySetCanceledWithBackgroundContinuationsTResult_RunsOnAnotherThread() { Test.Async(async () => { var unitTestThreadId = Thread.CurrentThread.ManagedThreadId; int continuationThreadId = unitTestThreadId; var tcs = new TaskCompletionSource<int>(); var continuation = tcs.Task.ContinueWith(_ => { continuationThreadId = Thread.CurrentThread.ManagedThreadId; }, TaskContinuationOptions.ExecuteSynchronously); tcs.TrySetCanceledWithBackgroundContinuations(); await continuation; Assert.AreNotEqual(unitTestThreadId, continuationThreadId); }); }