2017-10-13 1 views
3

Newbie to TPL in .NET. 시도중인 작업을 취소하기 위해 신호를받는 방법과 CancellationToken을 이해하려고 시도합니다. 아래 코드는 동일한 토큰이 두 작업에 모두 전달되는 경우 취소되는 하나의 작업 만 전송합니다. 내 가정은 첫 번째 작업에서 시간 제한이 발생하고 실행하는 경우입니다. ctx.Cancel() 두 작업을 모두 취소해야하는 이유는 하나의 예외 만보고있는 이유를 이해하는 데 약간의 도움이 필요합니다. 내가 누락 된 부분과 작업을 취소하고 메모리 자원을 사용하지 않도록하는 방법은 무엇입니까?CancellationToken이 모든 작업을 취소하지 않습니다.

static void Main(string[] args) 
    { 
     Console.WriteLine("Starting application"); 
     var ctx = new CancellationTokenSource(); 
     var token = ctx.Token; 
     try 
     { 
      var task1 = new Program().Run("task1", token); 
      var task2 = new Program().Run("task2", token); 

      if (!task1.Wait(1000)) 
       ctx.Cancel(); 

      task2.Wait(); 
     } 
     catch (AggregateException ex) 
     { 
      Console.WriteLine("Aggregate Exception occurred"); 
      foreach (var e in ex.InnerExceptions) 
      { 
       Console.WriteLine(e.Message); 
      } 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine($"Main Exception: {e.Message}"); 
     } 
     finally 
     { 
      Console.WriteLine("Finish Application"); 
      ctx.Dispose(); 
     } 
    } 

    private async Task Run(string name, CancellationToken token) 
    { 
     while(true) 
     { 
      if (token.IsCancellationRequested) 
      { 
       Console.WriteLine("Task Cancelled"); 
       token.ThrowIfCancellationRequested(); 
      } 
      Console.WriteLine($"Executing {name} ..."); 
      await Task.Delay(250, token);     
     } 
    } 

단 하나의 예외 만 발생합니다. 다른 작업은 어떻게됩니까? 또한 Console.WriteLine("Task Cancelled")이 실행되지 않았습니다.

출력 :

Starting application 
Executing task1 ... 
Executing task2 ... 
Executing task2 ... 
Executing task1 ... 
Executing task1 ... 
Executing task2 ... 
Executing task2 ... 
Executing task1 ... 
Aggregate Exception occurred 
A task was canceled. 
Finish Application 

답변

3

두 가지 :

  1. 당신은 Task.Delaythrowing 대신하여 취소 로직 ex.Flatten().InnerExceptions는 참조
  2. 에 대한 this에서 살펴 호출해야합니다. 로깅을 위해 try catch에 랩핑을 시도하십시오. 또는 tokenTask.Delay으로 전달할 수도 있습니다.
+0

CancellationToken을 Task.Delay에 전달하지 않으면 CancellationToken이 발생하는 지점이 누락됩니다. –

+0

@ JoeWhite, 당신이 요점을 가지고 있다고 가정 해 봅시다. 취소 처리 로직이 대신 사용되도록 제안합니다. – mrtig

+0

@mrtig 이것이 도움이 되겠지만 취소 토큰이 발행되면 모든 작업이 제대로 종료된다는 의미입니까? –

관련 문제