2014-10-29 1 views
1

작은 콘솔 응용 프로그램을 가지고 있으며 닫히기 전에 모든 프로세스가 완료 될 때까지 대기하는 데 문제가 있습니다. 이것이 일정대로 실행될 것이기 때문에, 나는 단지 Console.ReadKey 또는 그런 종류의 것을 추가 할 수 없습니다.비동기 적으로 처리 할 수있는 .Wait()을 대체 할 수있는 쉬운 방법이 있습니까?

첫 번째 비동기 메서드를 호출 할 때 앱의 나머지 코드를 계속 진행하지 못하도록 .Wait();을 추가해야했습니다. 나는 이것이 콘솔 응용 프로그램에서 할 수있는 수용 가능한 방법인지 또는 응용 프로그램이 닫히기 전에 비동기 메소드에서 대기하는지 확인하기위한 더 나은 방법 (잘만하면 간단 함)을 이해하려고합니다. 또한 응용 프로그램에서 사용하는 리소스의 양을 줄일 수 있기를 원하며, .Wait()은 리소스를 해제하는 대신 해당 스레드를 묶어 추가 리소스 사용으로 이어질 것이라는 것을 알고 있습니다.

다음은 내 논리가 배치 된 방법입니다.

private static List<string> taskList = new List<string>(); 
private static SemaphoreSlim mutex = new SemaphoreSlim(3); 

private static void Main(string[] args) 
{ 
    StartAllTasks().Wait(); // This LINE 
} 

private static async Task StartAllTasks() 
{ 
    await Task.WhenAll(taskList.Select(name => ProcessSingleTask(name))); 
} 

private async static Task ProcessSingleTask(string name) 
{ 
    await mutex.WaitAsync(); 
    try 
    { 
     TaskManager singleTask = new TaskManager(name); 
     await Task.Factory.StartNew(() => singleTask.ProcessTask()); 
    } 
    finally 
    { 
     mutex.Release(); 
    } 
} 

답변

0

올바른 것으로 보입니다. 주 스레드를 차단하려면 Wait() 호출이 필요합니다. 프로그램을 활성 상태로 유지하기 때문입니다. 스레드 차단은 너무 많은 리소스를 사용하는 것을 의미하지는 않습니다.

스레드가 반드시 스레드를 차단하지만 대기 호출 및 대기 호출은 CPU를 손상시키는 작업을 수행하지 않습니다.

스레드 또한 매우 가볍기 때문에 너무 걱정하지 마십시오!

+0

동의하지 않습니다. 우리는 항상 자원 소비에 대해 생각해야하며 스레드는 제한된 자원입니다. 여기서 우리는 어떻게 든 기다려야 만하지만, 일반적으로 동기화를 위해 결과를 기다리는 쓰레드를 소비하지 않도록주의해야합니다. 예를 들어, 그 때문에 우리는 부하가 많은 ASP.NET에서 스레드 풀을 훨씬 빠르게 소비 할 수 있습니다. –

+0

제가 대답 할 때 말했듯이, "너무 걱정하지 마십시오." 스레드를 사용하는 것만으로 나쁘지는 않습니다. 표시된 코드는 많은 스레드를 사용하지 않기 때문에 올바른 방법이므로 걱정할 필요가 없습니다. – Lukos

1

아니요, 귀하가 갖고있는 것이이 상황에서 최적의 방법입니다. 실제로 이는 Main 메서드 내부에서 Task을 기다리는 데 권장되는 방법입니다. 주 방법은 async 일 수 없으므로 메인 내부에 await을 사용할 수 없습니다.

누군가가 종료 할 때까지 다른 일반적인 옵션은 WaitHandle에서 기다리고 있습니다. 이는 실제로 가지고있는 것과 동일합니다. 그러니 그걸로 붙어있어.

다른 방법에 대해 이야기하는 경우 다른 이야기입니다. 그러나 Main의 경우 이것은 완벽합니다.

1

Wait은 콘솔의 Main에서 허용됩니다. 스레드를 "낭비"하지만 단일 스레드를 낭비하는 것은 대개 큰 문제가 아닙니다.

귀찮으면, async 코드에 실제로는 단일 스레드 컨텍스트를 제공하는 AsyncContext from my AsyncEx library을 사용할 수 있습니다. 또한 AggregateException에 예외를 래핑하지 않습니다. 그러나 이것은 async 코드가 스레드 풀 스레드에서 실행되지 않는다는 것을 의미합니다.이 코드는 모두 단일 콘솔 주 스레드에서 실행됩니다.

관련 문제