2016-02-24 43 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); 
}