How to combine TaskCompletionSource and CancellationTokenSource?

astrowalker picture astrowalker · Oct 6, 2016 · Viewed 13.6k times · Source

I have such code (simplified here) which awaits finishing task:

var task_completion_source = new TaskCompletionSource<bool>();
observable.Subscribe(b => 
   { 
      if (b) 
          task_completion_source.SetResult(true); 
   });
await task_completion_source.Task;    

The idea is to subscribe and wait for the true in the stream of booleans. This finishes the "task" and I can move on beyond the await.

However I would like to cancel -- but not subscription, but awaiting. I would like to pass cancel token (somehow) to task_completion_source so when I cancel the token source, the await will move on.

How to do it?

Update: CancellationTokenSource is external to this code, all I have here is the token from it.

Answer

Evk picture Evk · Oct 6, 2016

If I understand you correctly, you can do it like this:

using (cancellationToken.Register(() => {
    // this callback will be executed when token is cancelled
    task_comletion_source.TrySetCanceled();
})) {
    // ...
    await task_comletion_source.Task;
}

Note that it will throw an exception on your await, which you have to handle.