2016-02-24 33 views
3

所以我這段代碼:如何使用CancellationToken取消任務?

//CancelationToken 
CancellationTokenSource src = new CancellationTokenSource(); 
CancellationToken ct = src.Token; 
ct.Register(() => Console.WriteLine("Abbruch des Tasks")); 
//Task 
Task t = new Task(() => 
{ 
    System.Threading.Thread.Sleep(1000); 
    if (ct.IsCancellationRequested) 
    { 
     try 
     { 
      //Throw 
      ct.ThrowIfCancellationRequested();       
     } 
     catch (OperationCanceledException) 
     { 
      Console.WriteLine(
       "ThrowIfCancellationRequested() liefert eben eine Exception"); 
     } 
    }    

}, ct); 
//Run Task and Cancel 
t.Start(); 
src.CancelAfter(350); 
t.Wait(); 

// Get Information 
Console.WriteLine("Canceled: {0} . Finished: {1} . Error: {2}", 
        t.IsCanceled, t.IsCompleted, t.IsFaulted); 

因此,在這種情況下,我取消了我的工作,但我的最終輸出爲: 「取消:假成品:真正的錯誤:假」

在我看來,它應該是「取消:真實。完成:假」。 爲什麼我會得到這個結果?因爲我試圖捕捉異常?

我試過它沒有try - catch塊,但然後我的程序停止,因爲OperationCanceledException。有人能幫助我嗎?

+0

看一看[這裏](https://msdn.microsoft.com/en-us/library/dd997396 (v = vs.110)的.aspx)。刪除try..catch並放在't.Wait();'本質上。 –

回答

4

您正在吞嚥異常,因此任務會標記爲已完成,因爲您實際處理異常並且不會向外傳播。

相反,不抓委託內部異常,外面抓住它:

void Main() 
{ 
    CancellationTokenSource src = new CancellationTokenSource(); 
    CancellationToken ct = src.Token; 
    ct.Register(() => Console.WriteLine("Abbruch des Tasks")); 

    Task t = Task.Run(() => 
    { 
     System.Threading.Thread.Sleep(1000); 
     ct.ThrowIfCancellationRequested(); 
    }, ct); 

    src.Cancel(); 
    try 
    { 
     t.Wait(); 
    } 
    catch (AggregateException e) 
    { 
     // Don't actually use an empty catch clause, this is 
     // for the sake of demonstration. 
    } 

    Console.WriteLine("Canceled: {0} . Finished: {1} . Error: {2}", 
         t.IsCanceled, t.IsCompleted, t.IsFaulted); 
}