2016-12-07 1 views
4

저는 작업 기반 프로그래밍에 익숙하지 않고 작업을 반환하고 시작되었는지 확인하기 위해 새로운 방법을 사용합니다. 제가 일해야하는 코드는 제가 기대했던 것이 아니 었습니다. 콘솔 응용 프로그램은 다음과 같다 :반환되는 작업 및이 작업 상태가 이유는 무엇입니까? RanToCompletion

public static void Main(string[] args) 
    { 
     var mySimple = new Simple(); 
     var cts = new CancellationTokenSource(); 
     var task = mySimple.RunSomethingAsync(cts.Token); 
     while (task.Status != TaskStatus.RanToCompletion) 
     { 
      Console.WriteLine("Starting..."); 
      Thread.Sleep(100); 
     } 

     Console.WriteLine("It is started"); 
     Console.ReadKey(); 
     cts.Cancel(); 
    } 

public class Simple 
{ 
    public async void RunSomething(CancellationToken token) 
    { 
     var count = 0; 
     while (true) 
     { 
      if (token.IsCancellationRequested) 
      { 
       break; 
      } 
      Console.WriteLine(count++); 
      await Task.Delay(TimeSpan.FromMilliseconds(1000), token).ContinueWith(task => { }); 
     } 
    } 

    public Task RunSomethingAsync(CancellationToken token) 
    { 
     return Task.Run(() => this.RunSomething(token)); 
    } 
} 

출력은 : 우리가 볼로

Starting... 
0 
It is started 
1 
2 
3 
4 

왜 반환되는 작업이 TaskStatus.Running에 비해 TaskStatus.RanToCompletion 같은 상태가된다 루프가 아직 실행 중입니까? RunSomething 작업 자체보다는 스레드 풀에 RunSomething 작업을 넣는 작업의 상태를 확인하고 있습니까?

답변

3

RunSomethingasync void 메서드입니다.이 메서드는 호출자가 완료 시점을 결정할 방법이 없으므로 조작을 시작한 후에 다음에 어떤 일이 발생하는지 전혀 알 수 없습니다. 그런 다음 Task.Run 안에 전화를 겁니다. 이것은 시작RunSomething으로 스레드 풀 스레드를 스케 줄링합니다. 그런 다음 이 끝나 자마자Task으로 시작하여 완료됩니다.

RunSomething이 실제로 Task을 반환하면 호출자가 실제로 완료했을 때를 확인할 수 있고, 실제로 기다렸다가 실제로 비동기 작업이 완료 될 때까지 완료되었음을 나타내지는 않습니다 다른 테드에서 시작하려면 Task.Run을 사용할 이유가 없으므로 직접 호출하고 스레드 풀 스레드로 이동하는 노력을 낭비하지 않는 것이 좋습니다. 당신은 당신이해야한다 (예 : 정적 무효 메인에서와 같은) 비 비동기에서 비동기 메서드를 호출해야하는 경우

1
  1. 대신 당신이 작업

  2. 비동기 사용해야 비동기 무효 (https://msdn.microsoft.com/en-us/magazine/jj991977.aspx) 를 사용하지 마십시오

    mySimple.RunSomethingAsync(cts.Token).GetAwaiter().GetResult(); 
    

    이렇게하면 효과적으로 동기 호출을 수행 할 수 있습니다.