如果在没有完成任务的情况下超时,Task.Wait(int)是否会停止任务?

时间:2010-10-27 17:59:10

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

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

例如:

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

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

5 个答案:

答案 0 :(得分:52)

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

阅读精彩系列:Parallelism in .NETParallelism in .NET – Part 10, Cancellation in PLINQ and the Parallel class来自Reed Copsey

而且:.NET 4 Cancellation Framework / Parallel Programming: Task Cancellation

检查以下代码:

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();

答案 1 :(得分:15)

如果您要取消Task,则应在创建任务时传入CancellationToken。这样您就可以从外面取消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

答案 2 :(得分:7)

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

您可以查看等待的返回值:

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

类型:System.Boolean 如果任务在规定的时间内完成执行,则为true;否则,错误。

答案 3 :(得分:6)

  

当超时到期或任务是否仍在运行时,任务是否被取消?

不,是的。

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

答案 4 :(得分:0)

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

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

  • 该操作实际上已取消,并且所处理的资源处于稳定状态(您很幸运!)
  • 该操作实际上已取消,并且所处理的资源处于不一致状态(以后可能会引起各种问题)
  • 该操作继续进行,并且有可能干扰您其他代码的工作(以后可能会引起各种问题)
  • 操作失败或导致您的进程崩溃。
  • 您不知道会发生什么,因为它没有记录

在一些有效的情况下,您可以并且可能应该使用其他答案中描述的一种通用方法来取消任务。但是,如果因为要中断特定的同步方法而在此处,则最好查看该方法的文档,以了解是否有方法可以中断它,是否具有“ timeout”参数或是否存在可中断的变化形式。