有没有办法异步中止使用创建的 C# TPL 任务Task.Factory.Create(() => {stuff});
?我已经看到有一种方法可以使用 aCancellationToken
但我喜欢避免使用IsCancellationRequested
.
2 回答
编辑:针对 .NET 4.5 和更新版本进行了更新,详细信息在帖子底部。
这CancellationToken
是你想要使用的东西。检查IsCancellationRequested
可能看起来很痛苦,但它提供了一种处理取消的干净方法,而不是创建一个线程,然后中止它并且必须在并行运行的整个代码中处理线程中止异常。
var cts = new CancellationTokenSource();
var token = cts.Token;
var task = Task.Run(() =>
{
// Do Job Step 1...
if (token.IsCancellationRequested)
{
// Handle cancellation here, if necessary.
// Thanks to @svick - this will set the Task status to Cancelled
// by throwing OperationCanceledException inside it.
token.ThrowIfCancellationRequested();
}
// Do Job Step 2...
// ...
}, token);
// Later, to kill all the tasks and their children, simply:
cts.Cancel();
它可能会给委托增加一些混乱,但取消本身非常容易,以至于我不需要使用比取消令牌源更粗略的东西。你还没有说你为什么要避免它,所以除非有一些硬性限制,否则我会坚持使用取消令牌。
根据@ipavlu 的评论,对于像这样的简单用例,最好使用Task.Run
而不是原来Task.Factory.StartNew
的来触发异步工作。它们提供相同的基本功能,但Task.Run
具有更安全的默认值和对新功能的更好支持async
,同时Task.Factory.StartNew
可用于指定高级行为。更多信息,例如这里:https ://blogs.msdn.microsoft.com/pfxteam/2011/10/24/task-run-vs-task-factory-startnew/
取消可能很难实现,但这主要是因为取消,就像一般的并行处理一样,很复杂。您几乎肯定不希望允许在代码中的任意点中止,因为这会创建几乎与异步执行方法中的代码行一样多的新边界情况来测试。这是一种噩梦般的场景,会导致在野外发生几乎不可能重现的罕见崩溃。
设计异步流程的一部分是决定在哪里可以安全取消以及应该如何处理取消。这也可能意味着识别您进行的阻塞 API 调用(例如网络 I/O)并调用适当的方法来中断这些阻塞操作。适当地支持合作取消需要大量的前期设计工作,但是,如果需要该功能,前期投资将超过以后减少麻烦的回报。但是,这确实意味着您在将取消预算作为一项功能进行预算时要保守,因为它很少像听起来那么简单。