4

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

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

비동기 적으로 기다리는 방법은 무엇입니까?

1 답변


7

문제가 발생했습니다.async void. 당신이async람다를Action, 컴파일러는async void당신을위한 방법.

가장 좋은 방법은 피해야합니다.async void.

이를 수행하는 한 가지 방법은 실제 행동 목록을 실제로List<Func<Task>>대신에List<Action>. 이렇게하면 대기열에 넣을 수 있습니다.async Task대신에 방법async void행동 양식.

이것은 "실행"코드가 각각을 기다려야한다는 것을 의미합니다.Task완료되면. 또한 동기식 메서드는 반환해야합니다.Task.FromResult(0)또는 그와 비슷한 것이므로Func<Task>서명.

더 큰 범위의 솔루션을 원한다면 자신의 큐를 만드는 대신 TPL 데이터 흐름을 강력하게 고려하는 것이 좋습니다.

관련된 질문

최근 질문