2014-12-25 19 views
0

이 코드를 실행 중입니다.이 Task/CancellationToken 문제를 해결하는 방법은 무엇입니까?

using System; 
using System.Threading; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var task = DoSomething(); 
      Task.WaitAny(task); 

      Console.WriteLine(task.Result); 

      Console.Write("Press any key"); 
      Console.ReadKey(); 
     } 
     static void WriteLine(string str, params string[] param) 
     { 
      Console.WriteLine(str, param); 
      System.Diagnostics.Debug.WriteLine(str, param); 
     } 

     async static Task<string> DoSomething() 
     { 
      int timeout = 20; 
      int count = 1; 
      CancellationTokenSource cts; 
      string output;     
      do 
      { 
       cts = new CancellationTokenSource(timeout); 
       //does also happen with 
       //output = await Task<string>.Run(() => test(count, timeout, cts.Token)); 
       output = await Task<string>.Run(() => test(count, timeout, cts.Token), cts.Token); 

       if (cts.IsCancellationRequested) 
       { 
        WriteLine(string.Format("Retry. Count value {2}, Test Sleep time {0}, Method timeout {1}", output, timeout, count)); 
        timeout += 50; 
        count++; 
       } 
      } while (cts.IsCancellationRequested); 

      return string.Format("Count value {2}, Test Sleep time {0}, Method timeout {1}", output, timeout, count); 
     } 

     async static Task<string> test(int count, int timeout, CancellationToken ct) 
     { 
      int sleep = 400 - (count * 5); 
      await Task.Run(() => Task.Delay(sleep), ct); 

      if (!ct.IsCancellationRequested) 
      { 
       WriteLine(string.Format("Succeed. Count value {2}, Test Sleep time {0}, Method timeout {1}", sleep, timeout, count)); 
      } 
      return sleep.ToString(); 
     } 
    } 
} 

나는이 출력이

Retry. Count value 1, Test Sleep time 395, Method timeout 20 
Retry. Count value 2, Test Sleep time 390, Method timeout 70 
Retry. Count value 3, Test Sleep time 385, Method timeout 120 
Retry. Count value 4, Test Sleep time 380, Method timeout 170 
Retry. Count value 5, Test Sleep time 375, Method timeout 220 
Retry. Count value 6, Test Sleep time 370, Method timeout 270 
Retry. Count value 7, Test Sleep time 365, Method timeout 320 
Succeed. Count value 8, Test Sleep time 360, Method timeout 370 
Retry. Count value 8, Test Sleep time 360, Method timeout 370 
Succeed. Count value 9, Test Sleep time 355, Method timeout 420 

어떻게 Count value 8에서 문제를 해결하기 위해군요?

성공을 말하고 거기서 멈춰야합니다.

+0

참고 : 저는 timeout = 50을 사용하며 Xamarin에서 문제를 재현하지 못합니다. – tia

+0

'test' 메쏘드에서'CancellationToken'을 체크하면, 취소 된 상태가되고'DoSomething' 메쏘드 안에서'CancellationToken'을 체크합니다. – PetSerAl

+0

한 가지 질문은'output = await test (count, timeout, cts.Token); '를 사용하는 것입니다. – tia

답변

1

IsCancellationRequested은 "성공"및 "다시 시도"확인 중에 false에서 true으로 변경할 수 있기 때문에 문제는 경쟁 조건입니다. 이 코드의 실제 상황을 모른 채 올바른 수정을 제안하는 것은 어렵습니다.

관련 문제