namespace System.Threading.Tasks { internal static class TaskExtensions { public static async Task WithCancellation(this Task task, CancellationToken cancellationToken, Action onCancel) { var tcs = new TaskCompletionSource(); using (cancellationToken.Register(s => ((TaskCompletionSource)s).TrySetResult(true), tcs)) { if (task != await Task.WhenAny(task, tcs.Task).ConfigureAwait(false)) { try { onCancel(); } catch { } throw new OperationCanceledException(cancellationToken); } } return await task.ConfigureAwait(false); } } }