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

 Смежные вопросы

  • Нет связанных вопросов^_^