2010-10-27 20 views
26

我有一個任務,我期望它在一秒鐘內運行,但如果它需要超過幾秒鐘,我想取消任務。如果在沒有完成任務的情況下超時,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

回答

12

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

7

任務仍在運行,直到您明確告訴它停止或您的循環結束(這絕不會發生)。

您可以檢查等待的返回值來看到這一點:

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

類型:System.Boolean true,如果任務完成了規定的時間內執行;否則,是錯誤的。

5

超時過期或任務仍在運行時任務是否取消?

不,是且是。

超時傳遞給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

47

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

相關問題