【发布时间】:2014-01-27 20:28:19
【问题描述】:
我有这种情况:
private Task LongRunningTask = /* Something */;
private void DoSomethingMore(Task previousTask) { }
public Task IndependentlyCancelableSuccessorTask(CancellationToken cancellationToken)
{
return LongRunningTask.ContinueWith(DoSomethingMore, cancellationToken);
}
特别是,我在这里感兴趣的行为在MSDN's page about Continuation Tasks 中有以下详细说明:
在这些情况下,延续进入
Canceled状态:
- [...]
- 当延续传递一个
System.Threading.CancellationToken作为参数并且在延续运行之前令牌的IsCancellationRequested属性是true。在这种情况下,延续不会开始,而是转换到Canceled状态。
上面的代码有效。但是,我正在将尽可能多的延续转换为使用await 关键字。
是否有使用 await 的等效项,可以在等待的任务完成之前取消继续?
【问题讨论】:
-
好吧,我只是手动检查取消令牌,无论如何都会发生这种情况。也就是说,
if (!cancelled) await Task(); if (!cancelled) await Task2(); ...当然,您也可以将令牌传递给方法(也可以按照您想要的任何方式处理它)。 -
@Luaan:您的评论在概念上与Francois Nel's answer 相同,这并不能解决我的问题。
-
您确定在使用 ContinueWith 时它的工作方式有什么不同吗?我认为您也只能在任务之间取消,并且通过任务源代码搜索似乎支持这一点 - 无法取消任务本身(除非您自己在任务中处理取消),因为这完全取决于合作多任务,而不是先发制人。在某些时候,Task 类只是启动了您的委托,并且在您返回之前它不能做任何事情。你有没有试过
await和ContinueWith取消有区别吗? -
例如,您可以通过
await client.GetAsync(uri, cancellationToken);来等待 HttpClient 并取消。因此,除非Action委托本身(在托管代码之外“实现”,所以我不能肯定地说)或 ExecutionContext 中存在一些隐藏的魔法,否则您必须在您的方法中“手动”支持取消 - 通过有一个您照常使用的取消令牌参数。 -
另外,不要忘记
await和async使用相同的Task.ContinueWith方法来执行延续,因此没有理由相信它会以明显不同的方式工作。另请参阅 - msdn.microsoft.com/en-us/library/dd997364.aspx 和 microsoft.com/en-us/download/details.aspx?id=19957
标签: c# .net async-await