using System; using System.Threading; using System.Threading.Tasks; namespace GitHub.Runner.Common { //this code is documented on http://blogs.msdn.com/b/pfxteam/archive/2012/10/05/how-do-i-cancel-non-cancelable-async-operations.aspx public static class Extensions { public static async Task WithCancellation(this Task task, CancellationToken cancellationToken) { var tcs = new TaskCompletionSource(); using (cancellationToken.Register( s => ((TaskCompletionSource)s).TrySetResult(true), tcs)) if (task != await Task.WhenAny(task, tcs.Task)) throw new OperationCanceledException(cancellationToken); return await task; } public static async Task WithCancellation(this Task task, CancellationToken cancellationToken) { var tcs = new TaskCompletionSource(); using (cancellationToken.Register( s => ((TaskCompletionSource)s).TrySetResult(true), tcs)) if (task != await Task.WhenAny(task, tcs.Task)) throw new OperationCanceledException(cancellationToken); await task; } } }