2014-11-28 3 views
4

documentation에 따르면 Task.Run(Action, CancellationToken)은 작업이 취소되었을 때 TaskCanceledException을 던집니다.Task.Run (Action, CancellationToken)은 언제 TaskCanceledException을 throw합니까?

정확히 언제 Task.Run(Action, CancellationToken)TaskCanceledException을 던지시겠습니까? 이 예외가 발생하려면 어떤 조건을 충족시켜야하는지 명확하지 않습니다.

+1

은 당신은 당신의 질문에 연결된 사용자가 페이지의 예를 확인해 봤어? – zerkms

+0

@zerkms, 예제를 확인했습니다. TaskCanceledException은 Task.Run()이 아니라 Task.Wait() 메서드에 의해 throw됩니다. Task.Run()이 TaskCancelledException을 throw하는 조건을 이해하려고합니다. – Alex

답변

6

혼란이있는 것 같습니다. (설명서가 오도 할 수도 있습니다.)

Task.Run 방법을 Inoking 것 결코 던져 TaskCanceledException (적어도 현재의 구현). 및 ObjectDisposedException과 달리 "The action 매개 변수가 null"이고 "cancellationToken과 연결된 CancellationTokenSource가 삭제되었습니다"때 동 기적으로 throw됩니다. 각기.

Task.Run 그러나 던질 것 등 task.Wait(), task.Result를, (더 here에서 취소에서) CancellationToken 매개 변수를 사용하고 await task으로 기다리고 취소 될 수 Task을 반환하는 TaskCanceledException

(아마도 AggregateException에 싸여)
Task<int> task = null; 
try 
{ 
    task = Task.Run(() => 5, new CancellationToken(true)); 
} 
catch (TaskCanceledException) 
{ 
    Console.WriteLine("Unreachable code"); 
} 

try 
{ 
    int result = await task; 
} 
catch (TaskCanceledException) 
{ 
    Console.WriteLine("Awaiting a canceled task"); 
} 

설명서를 가능한 예외의 2 개 부분이 있다면 그것은 명확 수 있습니다 :

  1. "정기"동기 예외 (예 : ArgumentNullExceptionObjectDisposedException)만을 반환 작업에서 대기에 의해 발생 될 수
  2. "비동기"비동기 예외는 (예를 들어, TaskCanceledException)
+0

@ l3arnon, 이것은 매우 합리적으로 들립니다. Task.Run 메서드를 호출하면 결코 TaskCanceledException이 throw되지 않는다는 것을 어떻게 알았습니까? – Alex

+0

@Alex 잘, 경험.그러나 토끼 구멍을 내려 가려한다면 [Task.Run의 소스 코드] (http://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs)를 볼 수 있습니다. , 5faac53c590b086f), 동 기적으로 던져지는 다른 예외 만보십시오. – i3arnon

+0

설명서가 손상됩니다. – wayofthefuture

0
Cancellation in Managed Thread 읽기

:

만 요청 객체가 취소 요청을 발행 할 수 있으며, 각 청취자는 요청을 몰래 적시에 응답 할 책임이 있습니다.

취소가 협력 하고 청취자에 강제되지 않습니다에 다음

그리고 간다. 리스너는 취소 요청에 응답하여 정상적으로 종료하는 방법을 결정합니다.

CancellationToken.IsCancelledRequested에서 듣고 있는지 또는 CancellationToken.ThrowIfCancelltionRequested에서 예외를 수신하고 있는지 확인해야합니다. 그 귀하의 책임을 취소하고 await 취소 예외를 관찰하는 작업.

관련 문제