取消令牌的任务?

鉴于取消令牌,我想创建一个等待它的任务,这是永远不会完成但可以取消。 我需要这样的模式,IMO应该很常见:

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 } 

我到目前为止最好的想法是:

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

是否有更好的方法来实现这种逻辑?

它并不是非常常见,但它很常见,成为我的AsyncEx库的一部分。 我使用这样的东西 :

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

您在问题中建议的答案是我所知道的最佳解决方案。 原因如下:

  • 这很安全
  • 需要非常小的代码
  • 标准图书馆

根据我的知识,很多人大量使用Task.Delay方法,并且在Microsoft博客上也推荐使用。 MSDN示例 。

为什么要自己编写代码(包括测试)来利用TaskCompletionSource将取消令牌转换为任务? 最好是利用标准库而不是重新发明轮子; 它们比你的代码更容易出错。