如何将task.Wait(CancellationToken)转换为await语句?

因此, task.Wait()可以转换为await task 。 当然,语义是不同的,但这大致是我将使用Waits将阻塞代码转换为具有Waits的异步代码的方式。

我的问题是如何将task.Wait(CancellationToken)转换为相应的await语句?

创建一个代表现有任务但具有额外取消令牌的新Task非常简单。 您只需要在任务上调用ContinueWith ,使用新标记,并在连续体中传播结果/exception。

 public static Task WithCancellation(this Task task, CancellationToken token) { return task.ContinueWith(t => t.GetAwaiter().GetResult(), token); } public static Task WithCancellation(this Task task, CancellationToken token) { return task.ContinueWith(t => t.GetAwaiter().GetResult(), token); } 

这允许您编写task.WithCancellation(cancellationToken)以将令牌添加到任务,然后您可以await该任务。

await用于异步方法/委托,它接受CancellationToken ,因此你应该在调用它时传递一个(即await Task.Delay(1000, cancellationToken) ),否则它们不会被取消(例如,等待I / O结果)。

但是,您可以使用此扩展方法放弃*这些类型的任务:

 public static Task WithCancellation(this Task task, CancellationToken cancellationToken) { return task.IsCompleted // fast-path optimization ? task : task.ContinueWith( completedTask => completedTask.GetAwaiter().GetResult(), cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); } 

用法:

 await task.WithCancellation(cancellationToken); 

*被放弃的任务不会被取消,但您的代码表现得像是一样。 它要么以结果/exception结束,要么永远保持活力。