mar*_*ark 12 .net c# task-parallel-library async-await
所以,task.Wait()可以转化为await task.当然,语义是不同的,但这大致是我将阻塞代码Waits转换为异步代码的方法awaits.
我的问题是如何转变task.Wait(CancellationToken)为各自的await声明?
await用于异步方法/委托,它们接受a CancellationToken,因此你应该在调用它时传递一个(即await Task.Delay(1000, cancellationToken)),或者它们不传递它们,它们实际上不能被取消(例如等待I/O结果).
但是,您可以使用此扩展方法放弃*这些类型的任务:
public static Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{
return task.IsCompleted // fast-path optimization
? task
: task.ContinueWith(
completedTask => completedTask.GetAwaiter().GetResult(),
cancellationToken,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default);
}
Run Code Online (Sandbox Code Playgroud)
用法:
await task.WithCancellation(cancellationToken);
Run Code Online (Sandbox Code Playgroud)
*被放弃的任务不会被取消,但您的代码就像它有一样.它要么以结果/异常结束,要么永远保持活力.
创建Task表示现有任务但具有额外取消令牌的新内容非常简单.您只需要调用ContinueWith任务,使用新标记,并在连续体中传播结果/异常.
public static Task WithCancellation(this Task task,
CancellationToken token)
{
return task.ContinueWith(t => t.GetAwaiter().GetResult(), token);
}
public static Task<T> WithCancellation<T>(this Task<T> task,
CancellationToken token)
{
return task.ContinueWith(t => t.GetAwaiter().GetResult(), token);
}
Run Code Online (Sandbox Code Playgroud)
这允许您编写task.WithCancellation(cancellationToken)以向任务添加令牌,然后您可以执行此操作await.
| 归档时间: |
|
| 查看次数: |
1753 次 |
| 最近记录: |