【问题标题】:How do I force a task cancellation?如何强制取消任务?
【发布时间】:2011-03-14 13:19:18
【问题描述】:

假设,有一个任务大致包含以下动作:

Task someTask = new Task(() => {

  while(!IsCancellationRequested) {

    Do_something_over_a_long_period_of_time();
    token.ThrowIfCancellationRequested();

    Do_something_over_a_long_period_of_time();
    token.ThrowIfCancellationRequested();

    Do_something_over_a_long_period_of_time();
    token.ThrowIfCancellationRequested();
  }
});
someTask.Start();

而且有相当不耐烦的用户。他们渴望立即终止我的申请。他们不想在长时间的操作运行时等待。

我曾经使用Thread 类,并且能够通过调用Abort() 命令立即中止我的所有线程。

如何立即中止我的任务?

谢谢。

【问题讨论】:

  • 你看过BackgroundWorker吗?
  • @HadleyHope Background Worker 如何解决他的问题。它支持与任务类似的取消方式

标签: c# multithreading task task-parallel-library


【解决方案1】:

您不能以不合作的方式强制任务中止。以不受控制的方式中止线程是不安全的,因此故意不受支持。

您应该让您的 Do_something_over_a_long_period_of_time 呼叫改为可取消(即,将令牌传递给他们,并让 他们 也定期检查)。

编辑:正如另一个答案中所述,您可以通过确保所有前台线程都已终止来终止 应用程序。但是您需要注意,您的任务不一定有机会干净地 终止。如果他们正在做诸如写入文件之类的事情,您可能希望等到注意到取消,以避免破坏持久状态。

【讨论】:

  • 谢谢。这对我很有用。
  • 因此,如果我启动一个只调用单个方法 GetDataThatRunsForTheNext40secs() 的新任务,那么就没有办法立即从外部取消任务吗?这种取消的结果并不重要——但我希望我的 CPU 尽快做有用的事情。想法?
  • @Gishu:如果没有相关任务的合作,我不知道有什么方法可以安全地做到这一点。
  • 归根结底,Do_something_over_a_long_period_of_time 可能是第 3 方库调用,您无法将其修改为可合作取消。因此,能够强制取消此类任务仍然是一个合法的现实世界要求。是的,杀死它的线程可能安全也可能不安全,具体取决于函数正在执行的工作(I/O 等),但是除了“不要这样做”之外,必须有一个最好的方法。
  • 我同意不能安全终止任意代码。我想到了一个特定的场景:我们正在运行一个 CPU 密集型数学“求解器”,它可能需要几分钟才能运行。它只是简单地处理数字,最终返回结果,但不执行 I/O(尽管它可能会分配非托管内存等)。我们必须能够取消它,但我们不能更改库。我们做什么?我能想到的最佳解决方案是每个计算单独的进程,或者可能是一个AppDomain?
【解决方案2】:

他们渴望立即终止我的申请。他们不想在长时间运行时等待。

默认情况下,任务在线程池上作为后台任务运行。您可以安全地退出应用程序,而无需担心后台线程。

所以只要你想退出你的进程就没有问题。

请注意,Thread.Abort() 快速但不安全。即使是退出应用程序也不行,但它很少会引起真正的问题。

【讨论】:

  • 我不认为我会说“没有问题”——如果其中一个后台线程正在编写应用程序下次启动时需要的文件怎么办?
  • 我忘记了线程池和后台任务。它现在工作正常。谢谢。
猜你喜欢
  • 2014-04-22
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
  • 2018-09-05
  • 2017-08-24
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多