【问题标题】:Task.Run with cancellation supportTask.Run 取消支持
【发布时间】:2015-02-17 16:40:59
【问题描述】:

考虑this Task.Run example。它显示了如何创建具有取消支持的任务。

我正在做类似的事情:

Task.Run(()=>{while (!token.IsCancellationRequested()) {...}}, token);

我的问题:

  1. 既然我已经有了对取消令牌的引用,为什么要将它作为参数传递给Task.Run 调用?

  2. 我经常在示例中看到如下代码:

    if (token.IsCancellationRequested) token.ThrowIfCancellationRequested();

这段代码的目的是什么?为什么不只是 return 来自方法?

【问题讨论】:

  • 我只是想回答,但 Sriram 的回答涵盖了它。但是您不必使用if (token.IsCancellationRequested) ...,因为ThrowIfCancellationRequested 已经检查过了。
  • @Dirk 我刚刚也提到了:)

标签: c# task-parallel-library


【解决方案1】:
  1. 如果您将取消令牌传递给Task.Run,如果令牌在任务启动之前被取消,它将永远不会开始为您节省资源(我的意思是不创建线程等)。

  2. 如果只是从方法中返回,则任务的状态不会是Canceled,而是RanToCompletion。显然这不是你所期望的。

或者,您可以将OperationCanceledExceptionCancellationToken 作为参数一起抛出,这将使Task.Status 成为Canceled,但这是一种艰难而冗长的方式。 token.ThrowIfCancellationRequested 简洁明了。

您可以简单地使用token.ThrowIfCancellationRequested();,无需检查token.IsCancellationRequestedThrowIfCancellationRequested 方法已经这样做了。

【讨论】:

  • 很好的答案,只有一个问题:如果发生这种情况,ThrowIfCancellationRequested 会引发错误。使用异常处理工作流不是不好的做法吗?
  • @MatthiasMüller 好问题。但是取消不是正常的控制流程,对吧?这意味着您对已启动的任务不感兴趣。 BCL 的设计者为此选择使用例外来传达取消。就像你去酒店,点了一些需要很长时间才能上菜的东西,你不能再等了,说我不再需要那些废话了。取消它! 由于这不是常见的事情,他们选择使用例外是我的猜测。否则,您需要标志,如果有嵌套的方法调用,您将无法轻松处理。你明白我的意思吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
相关资源
最近更新 更多