繁体   English   中英

异步中止C#TPL任务

[英]Asynchronously abort C# TPL Tasks

有没有一种方法可以异步中止使用Task.Factory.Create(() => {stuff});创建的C#TPL任务Task.Factory.Create(() => {stuff}); 我已经看到有一种使用CancellationToken进行此操作的方法,但我想避免使用IsCancellationRequested进行检查。

编辑:针对.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),并调用适当的方法来中断这些阻止操作。 要正确地支持协作取消,需要大量的前期设计工作,但是,如果需要此功能,则前期投资将在以后减少头痛方面获得更大的回报。 但是,这的确确实意味着您要保守地将取消作为一项功能进行预算,因为它很少像听起来那样简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM