2013-07-09 4 views
4

비동기 적으로 지연되는 작업을 가져 오는 데 문제가 있습니다. 수십만/수십만 개의 비동기 적으로 실행되는 스크립트를 실행해야하는 응용 프로그램을 작성하고 있습니다. C# 작업을 사용하여이 작업을 수행하고 때로는 특정 시퀀스를 실행하는 동안 스크립트가 제대로 실행 되려면 예상 된 상태에 도달하기 위해 외부 리소스를 기다려야합니다. 처음에는 Thread.Sleep()을 사용하여이 코드를 작성했지만 응용 프로그램 성능에 어뢰가되는 것으로 밝혀 졌으므로 비동기/비동기 수면을 기다리고 있습니다. 하지만 실제로 일시 중지를 기다릴 수는 없습니다! 누군가 이것을 설명 할 수 있습니까? 실행의C# async 작업에서 Task.delay 대기 중

static void Main(string[] args) 
    { 
     var sync = new List<Action>(); 
     var async = new List<Action>(); 

     var syncStopWatch = new Stopwatch(); 
     sync.Add(syncStopWatch.Start); 
     sync.Add(() => Thread.Sleep(1000)); 
     sync.Add(syncStopWatch.Stop); 
     sync.Add(() => Console.Write("Sync:\t" + syncStopWatch.ElapsedMilliseconds + "\n")); 

     var asyncStopWatch = new Stopwatch(); 
     sync.Add(asyncStopWatch.Start); 
     sync.Add(async() => await Task.Delay(1000)); 
     sync.Add(asyncStopWatch.Stop); 
     sync.Add(() => Console.Write("Async:\t" + asyncStopWatch.ElapsedMilliseconds + "\n")); 

     foreach (Action a in sync) 
     { 
      a.Invoke(); 
     } 

     foreach (Action a in async) 
     { 
      a.Invoke(); 
     } 
    } 

결과는 다음과 같습니다

동기화 : 999

비동기 : 2

어떻게 내가 비동기 기다려야합니까?

답변

7

async void에 문제가 있습니다. async 람다를 Action에 전달하면 컴파일러에서 async void 메서드를 만듭니다.

모범 사례로는 async void을 피해야합니다.

한 가지 방법은 실제로 작업 목록을 List<Action> 대신 List<Func<Task>>이되도록하는 것입니다. 이렇게하면 async void 메서드 대신 async Task 메서드를 대기시킬 수 있습니다.

이것은 당신의 "실행"코드가 완료 각 Task 기다려야 할 것입니다 의미합니다. 또한, 당신의 동기 방법은 같은 Task.FromResult(0) 또는 뭔가를 반환해야합니다 그래서 그들은 Func<Task> 서명과 일치. 당신이 더 큰 범위의 솔루션을 원하는 경우에

, 난 당신이 강력하게 자신의 큐를 만드는 대신 TPL 데이터 흐름을 고려하는 것이 좋습니다.

관련 문제