有没有办法异步中止使用Task.Factory.Create(() => {stuff});
创建的C#TPL任务?我已经看到有一种方法可以使用CancellationToken
进行操作,但我希望避免使用IsCancellationRequested
进行检查。
答案 0 :(得分:8)
编辑:已更新.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/
答案 1 :(得分:7)
取消可能很难实现,但这主要是因为取消,如一般的并行处理,很复杂。您几乎肯定不希望允许在代码中的任意点中止,因为这会创建几乎同样多的新可能边界情况进行测试,因为在异步执行的方法中存在代码行。这是一种噩梦般的场景,导致野外罕见的崩溃,几乎不可能重现。
设计异步流程的一部分是决定取消安全的位置以及应如何处理取消。这也可能意味着识别您进行的阻塞API调用(例如网络I / O)并调用适当的方法来中断这些阻塞操作。需要大量的前期设计工作来正确支持合作取消,但是,如果需要该功能,前期投资将在以后减少头痛中获得回报。但是,这确实意味着你在预算取消作为一项功能时要保守,因为它很少像听起来那么简单。