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

问题描述:

我有一个任务,我期望它在一秒钟内运行,但如果它需要超过几秒钟,我想取消任务。如果在没有完成任务的情况下超时,Task.Wait(int)是否会停止该任务?

例如:

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

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

+2

为什么不使用取消API? – 2010-10-27 18:03:08

+0

什么是取消API? – 2010-10-27 18:10:58

+0

检查我的答案我把它的一些链接 – 2010-10-27 18:19:37

如果你想取消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); 

要取消对tokenSourceTask呼叫Cancel()

+3

这难道不允许你只从外部请求*取消吗?请问代表是否关注基于令牌的请求并实际抛出或继续工作而不取消? – BitMask777 2014-11-20 22:06:04

+0

更正,代理通过检查属性上的IsCancellationRequest来决定它是否会对请求执行操作。 – 2014-11-21 16:44:37

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

您可以检查等待的返回值来看到这一点:

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

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

超时过期或任务仍在运行时任务是否取消?

不,是且是。

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

+0

这很有趣,因为帮助文本这里似乎有相反的说法:https://msdn.microsoft.com/en-us/library/dd270644(v=vs.110).aspx说,_“等待任务在指定的毫秒数内完成执行“_不确定我是否理解这一点。 – 2015-04-30 18:10:47

+0

@Michael如果传递给Wait的时间到期,它将返回,即使任务尚未完成。在这种超时的情况下,任务将继续执行直到完成(并且稍后的“等待”将因此完成而返回)。 – Richard 2015-05-01 07:20:24

Task.Wait()等待高达任务完成的指定期限并返回是否在指定的时间(或更早)完成任务。任务本身没有被修改,也不依赖于等待。

阅读不错系列:Parallelism in .NETParallelism in .NET – Part 10, Cancellation in PLINQ and the Parallel class由Reed科普塞

和:.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(); 
+0

谢谢昵称这是一个很棒的代码 – 2014-10-20 10:19:10

+0

我很高兴帮助你 – 2014-10-20 17:14:56

+0

我注意到'cts.Token'也传递给'Wait()'方法。我在Microsoft的文档中发现了一个注释:_“将cancellationToken对象传递给此方法只是允许根据某些条件取消等待。”_ https://msdn.microsoft.com/en-us/library/dd321457%28v = vs.110%29.aspx – 2015-04-30 22:24:42