비동기식으로 작업을 지연시키는 데 문제가 있습니다. 수십만 / 수십만 개의 비동기 적으로 실행되는 스크립트를 실행해야하는 응용 프로그램을 작성하고 있습니다. 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
비동기 적으로 기다리는 방법은 무엇입니까?
문제가 발생했습니다.async void
. 당신이async
람다를Action
, 컴파일러는async void
당신을위한 방법.
가장 좋은 방법은 피해야합니다.async void
.
이를 수행하는 한 가지 방법은 실제 행동 목록을 실제로List<Func<Task>>
대신에List<Action>
. 이렇게하면 대기열에 넣을 수 있습니다.async Task
대신에 방법async void
행동 양식.
이것은 "실행"코드가 각각을 기다려야한다는 것을 의미합니다.Task
완료되면. 또한 동기식 메서드는 반환해야합니다.Task.FromResult(0)
또는 그와 비슷한 것이므로Func<Task>
서명.
더 큰 범위의 솔루션을 원한다면 자신의 큐를 만드는 대신 TPL 데이터 흐름을 강력하게 고려하는 것이 좋습니다.