Jea*_*nal 11 .net c# async-await
我有这种情况:
private Task LongRunningTask = /* Something */;
private void DoSomethingMore(Task previousTask) { }
public Task IndependentlyCancelableSuccessorTask(CancellationToken cancellationToken)
{
return LongRunningTask.ContinueWith(DoSomethingMore, cancellationToken);
}
Run Code Online (Sandbox Code Playgroud)
特别是,我在这里感兴趣的行为在MSDN的关于Continuation Tasks的页面中详细说明如下:
Canceled在这些场景中,延续进入状态:
- [...]
- 当继续
System.Threading.CancellationToken作为参数传递IsCancellationRequested时,令牌的属性true在继续运行之前.在这种情况下,延续不会开始,它会转换到Canceled状态.
上面的代码有效.但是,我正在尽可能多地使用await关键字转换我的延续.
是否存在等效使用await,允许在等待任务完成之前取消继续?
以下应该这样做,虽然看起来有点尴尬:
private Task LongRunningTask = /* Something */;
private void DoSomethingMore() { }
public async Task IndependentlyCancelableSuccessorTask(
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var tcs = new TaskCompletionSource<bool>();
using (cancellationToken.Register(() => tcs.TrySetCanceled()))
await Task.WhenAny(LongRunningTask, tcs.Task);
cancellationToken.ThrowIfCancellationRequested();
DoSomethingMore();
}
Run Code Online (Sandbox Code Playgroud)
[更新]根据svick的建议,在这里它被塑造成一个帮手,基于Stephen Toub的实施然后与等待模式:
public static class TaskExt
{
/// <summary>
/// Use: await LongRunningTask.Then(DoSomethingMore, cancellationToken)
/// </summary>
public static async Task Then(
this Task antecedent, Action continuation, CancellationToken token)
{
await antecedent.When(token);
continuation();
}
/// <summary>
/// Use: await LongRunningTask.When(cancellationToken)
/// </summary>
public static async Task When(
this Task antecedent, CancellationToken token)
{
token.ThrowIfCancellationRequested();
var tcs = new TaskCompletionSource<Empty>();
using (token.Register(() => tcs.TrySetCanceled()))
await Task.WhenAny(antecedent, tcs.Task);
token.ThrowIfCancellationRequested();
}
struct Empty { };
}
Run Code Online (Sandbox Code Playgroud)
也许,第一个ThrowIfCancellationRequested()是多余的,但我没有彻底考虑所有边缘情况.
| 归档时间: |
|
| 查看次数: |
1328 次 |
| 最近记录: |