35

我有一个任务,我希望它需要不到一秒钟的时间才能运行,但如果它需要的时间超过几秒钟,我想取消该任务。

例如:

Task t = new Task(() =>
        {
            while (true)
            {
                Thread.Sleep(500);
            }
        });
t.Start();
t.Wait(3000);

请注意,在 3000 毫秒后等待到期。超时后任务被取消还是任务仍在运行?

4

5 回答 5

54

Task.Wait()等待任务完成的指定时间段,并返回任务是否在指定的时间量(或更早)内完成任务本身不被修改,不依赖等待。

阅读不错的系列:.NET 中的并行性,.NET中的并行性 - 第 10 部分,PLINQ 中的取消和Reed Copsey的 Parallel 类

和:.NET 4 取消框架/ 并行编程:任务取消

检查以下代码:

var cts = new CancellationTokenSource();

var newTask = Task.Factory.StartNew(state =>
                           {
                              var token = (CancellationToken)state;
                              while (!token.IsCancellationRequested)
                              {
                              }
                              token.ThrowIfCancellationRequested();
                           }, cts.Token, cts.Token);


if (!newTask.Wait(3000, cts.Token)) cts.Cancel();
于 2010-10-27T18:07:15.077 回答
16

如果要取消 a Task,则应在CancellationToken创建任务时传入 a 。这将允许您Task从外部取消。如果需要,您可以将取消绑定到计时器。

要使用取消令牌创建任务,请参见以下示例:

var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;

var t = Task.Factory.StartNew(() => {
    // do some work
    if (token.IsCancellationRequested) {
        // Clean up as needed here ....
    }
    token.ThrowIfCancellationRequested();
}, token);

取消Task通话。Cancel()_tokenSource

于 2010-10-27T18:20:54.803 回答
7

该任务仍在运行,直到您明确告诉它停止或您的循环完成(这永远不会发生)。

您可以检查 Wait 的返回值来查看:

(来自http://msdn.microsoft.com/en-us/library/dd235606.aspx)返回值

类型:System.Boolean 如果任务在分配的时间内完成执行,则为真;否则为假。

于 2010-10-27T18:03:35.157 回答
6

超时后任务被取消还是任务仍在运行?

不和是。

传递给的超时Task.Wait是针对 的Wait,而不是针对任务的。

于 2010-10-27T18:04:09.977 回答
-1

如果您的任务调用任何同步方法来执行任何类型的 I/O 或其他需要时间的未指定操作,那么没有通用的方法可以“取消”它。

根据您尝试“取消”它的方式,可能会发生以下情况之一:

  • 该操作实际上被取消并且它所处理的资源处于稳定状态(你很幸运!)
  • 该操作实际上被取消并且它所处理的资源处于不一致的状态(以后可能会导致各种问题)
  • 该操作继续进行,并可能干扰您的其他代码正在执行的任何操作(以后可能会导致各种问题)
  • 操作失败或导致您的进程崩溃。
  • 你不知道会发生什么,因为它是无证的

在某些有效的场景中,您可以并且可能应该使用其他答案中描述的通用方法之一取消任务。但是如果你在这里是因为你想中断一个特定的同步方法,最好查看该方法的文档,看看是否有办法中断它,是否有“超时”参数,或者是否有可中断的变化其中。

于 2019-12-02T10:04:40.110 回答