Task from cancellation token?

妖精的绣舞 提交于 2019-12-17 19:57:54

问题


Given a cancellation token, I'd like to create an awaitable task out of it, which is never complete but can be cancelled. I need it for a pattern like this, which IMO should be quite common:

async Task DoStuff(Task t, CancellationToken ct)
{
   // t was made from TaskCompletionSource, 
   // both t and ct are beyond my control

   Task t2 = TaskFromCancellationToken(ct);
   await Task.WhenAny(t, t2);

   // do stuff
}

The best idea I've got so far is this:

Task TaskFromCancelationToken(CancellationToken ct)
{
    return Task.Delay(Timeout.Infinite, ct);
}

Is there a better way to make this logic happen?


回答1:


It's not extremely common, but it's common enough to be part of my AsyncEx library. I use something like this:

public static Task AsTask(this CancellationToken cancellationToken)
{
    var tcs = new TaskCompletionSource<object>();
    cancellationToken.Register(() => tcs.TrySetCanceled(),
        useSynchronizationContext: false);
    return tcs.Task;
}



回答2:


Task.Delay(Timeout.Infinite, cancellationToken)

The answer you suggest in your question is the best solution to my knowledge. Here's why:

  • It is safe
  • Very small piece of code required
  • Standard library

The Task.Delay approach is heavily used by a lot of folks as per my knowledge, and is also recommended on Microsoft blogs. MSDN Example.

Why write code (including tests) yourself leveraging TaskCompletionSource for converting a cancellation token to a task? It is preferable to leverage the standard libraries instead of reinventing the wheel; they are more likely to be bug free than your code.



来源:https://stackoverflow.com/questions/18670111/task-from-cancellation-token

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!