2012-08-26 3 views
3

취소 :작업 상태가 될 때 다음 코드 내가 쓴

CancellationTokenSource tokenSource = new CancellationTokenSource(); 
CancellationToken token = tokenSource.Token; 

int i = 0; 
Console.WriteLine("Calling from Main Thread {0}", System.Threading.Thread.CurrentThread.ManagedThreadId); 

Task t1 = new Task(() => 
{ 
    while (true) 
    { 
     try 
     { 
      token.ThrowIfCancellationRequested(); 
     } 

     catch (OperationCanceledException) 
     { 
      Console.WriteLine("Task1 cancel detected"); 
      break; 
     } 

     Console.WriteLine("Task1: Printing: {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, i++); 
    } 
}, token); 

Task t2 = new Task(() => 
{ 
    while (true) 
    { 
     try 
     { 
      token.ThrowIfCancellationRequested(); 
     } 

     catch (OperationCanceledException) 
     { 
      Console.WriteLine("Task2 cancel detected"); 
      break; 
     } 

     Console.WriteLine("Task2: Printing: {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, i++); 
    } 
}); 

t1.Start(); 
t2.Start(); 
Thread.Sleep(100); 
tokenSource.Cancel(); 

t1.Wait();//wait for thread to completes its execution 
t2.Wait();//wait for thread to completes its execution 
Console.WriteLine("Task1 Status:{0}", t1.Status); 
Console.WriteLine("Task2 Status:{0}", t1.Status); 

여기에 내가 다음 작업을 취소하고도 상태가 RanToCompletion을 보여줍니다하지만 난 모두 작업에 대기를 제거하는 경우, 다음 날 취소 된 상태를 보여줍니다 .. . MSDN 에서을 사용하여 OperationCanceledException을 던지고 일을 전달함으로써 :

내가 작업을 취소하고, 나는 어떤 경우에도 취소 된 상태 ...

편집을 기대하고있다 e 취소 요청이있는 토큰. 이 작업을 수행하는 가장 좋은 방법은 ThrowIfCancellationRequested 메서드를 사용하는 것입니다. 이 방법으로 취소 된 작업은 취소 된 상태로 전환되며, 호출 코드는 작업이 취소 요청에 응답했는지 확인하는 데 사용할 수 있습니다.

Wait 또는 WaitAll 메서드를 사용하여 작업을 기다리지 않으면 해당 작업의 상태가 Canceled로 설정됩니다.

답변

6

OperationCanceledException을 catch하고 while 루프를 종료하면 작업이 정상적으로 종료되고 작업 상태가 RanToCompletion이됩니다.

Canceled 상태를 가져 오려면 OperationCanceledException을 다시 throw하거나 전혀 catch하지 않아야합니다.

작업 자체 CancellationToken와 함께 하여 OperationCanceledException을 던져 취소를 인정한 토큰이 신호 상태에있는 동안, 또는 작업의 CancellationToken 이미 을했다 : 작업 상태 MSDN에 따르면

이 경우 취소됩니다 작업이 실행되기 전에 신호를받습니다. 에 대한 자세한 내용은 Task Cancellation을 참조하십시오.

소스 코드에서 예외를 삼켰으므로 작업 상태는 RanToCompletion이 될 것입니다.

대기를 제거 할 때 상태가 취소 된 이유에 대한 질문에 대답하려면 예외가 아직 포착되지 않았으며 취소 상태가 이전에 확인 되었기 때문일 수 있습니다. 이 동작은 안정적이고 재현 가능하지 않아야합니다.

+0

thanks ziad. 그러나 작업 대기 시간을 제거하면 취소 된 상태가되어 일부 혼란 스럽습니다. –

+0

MSDN 링크의 질문을 업데이트했습니다. 업데이트 한 문에 대해 여전히 혼란 스럽습니다. 그것은 최후의 성명서와 모순 되는가? –

+0

@RaoBHavik 당신이 Wait를 할 때 상태가 취소되었다는 사실은 전적으로 우연이라고 생각합니다. 사실 Thread.Sleep (5000)에 의한 두 개의 대기를 대체하면 작업 상태는 아마 RanToCompletion이됩니다. –

관련 문제