Task-based Asynchronous Pattern – WithCancellation


if you’re working with a Task based API that does not follow the TAP rules and hence does not expose an option to cancel you can always add your own this way:

 1: public static Task<T> WithCancellation<T>(
 2:     this Task<T> task, 
 3:     CancellationToken cancellationToken)
 4: {
 5:     var taskCompletionSource = new TaskCompletionSource<T>();
 6:     var cancellationRegistration = cancellationToken.Register(
 7:         () => taskCompletionSource.TrySetCanceled());
 8:     task.ContinueWith(
 9:         t =>
 10:             {
 11:                 cancellationRegistration.Dispose();
 12:                 if (t.IsCanceled)
 13:                 {
 14:                     taskCompletionSource.TrySetCanceled();
 15:                 }
 16:                 else if (t.IsFaulted)
 17:                 {
 18:                     taskCompletionSource.TrySetException(
 19:                         t.Exception.InnerException);
 20:                 }
 21:                 else
 22:                 {
 23:                     taskCompletionSource.TrySetResult(t.Result);
 24:                 }
 25:             });
 26:     return taskCompletionSource.Task;
 27: }

This naturally will not actually stop the task you wrap this way but at least it returns control to the code waiting for completion faster.

Comments (0)

Skip to main content