6

다음 코드에서 task1과 task2는 서로 독립적이며 병렬로 실행할 수 있습니다. 다음 두 구현 간의 차이점은 무엇입니까?

var task1 = GetList1Async();
var task2 = GetList2Async();

await Task.WhenAll(task1, task2);

var result1 = await task1; 
var result2 = await task2; 

var task1 = GetList1Async();
var task2 = GetList2Async();

var result1 = await task1; 
var result2 = await task2; 

왜 다른 하나를 선택해야합니까?

편집 : GetList1Async () 및 GetList2Async () 메서드의 반환 형식을 추가하려면 다른 싶습니다.


  • I4v, 첫 번째 경우,var result = await task1;~의 정확한var result = task1.Result. 나는 그렇게 생각한다..Result그래도 더 읽기 쉽습니다. - dcastro
  • @ I4V 아니. 두 조각 모두에서 작업은 순차적으로가 아니라 병렬로 실행됩니다. - Servy
  • @dcastro, 그들은 동일하지 않습니다. 예외의 경우 .Result를 사용하면 다른 예외가 생성됩니다 (AggregateException)를 사용할 때보 다await(첫 번째 예외), 그래서async/await당신은await위에.Result예외 동작을 일관되게 유지합니다. - Matt Smith
  • 그러나 예외가 발생하면 모든 것을 기다릴 때 던져 지므로 그 아래의 두 줄을 절대 지나칠 수 없습니다. 그 아래에있는 두 줄로 가면 예외가 발생하거나 교착 상태가 발생하지 않도록 할 수 있습니다. 이미 완료된 작업을 보장 할 수 있습니다. 인용하다stackoverflow.com/a/24657079/1676558. - user1676558

2 답변


10

첫 번째 예에서는 두 작업이 모두 완료 될 때까지 기다린 다음 두 작업의 결과를 검색합니다.

두 번째 예는 작업이 한 번에 하나씩 완료 될 때까지 기다립니다.

코드에 대해 더 명확한 것을 사용해야합니다. 두 작업의 결과 유형이 같으면 결과를 검색 할 수 있습니다.WhenAll그와 같이 :

var results = await Task.WhenAll(task1, task2);


  • 의도 명확성과 별개로 조건이 맞으면 (2 개 이상의 CPU 코어가 유휴 상태 일 때) 솔루션 1이 솔루션 2보다 더 많이 병렬화 될 가능성이 있습니까? - Snakebyte
  • @ Snakebyte 아니, 그렇지 않아. 첫 번째 경우에는 오버 헤드가 거의 발생하지 않으며 둘 다 동일하게 수행됩니다.WhenAll불필요하게. - Servy
  • @ 세이 비 : 정확히 무엇을 의미합니까? 내가 이해하고 스테판은 example1에서 task1과 task2가 병렬로 실행된다는 것을 알고 있습니다. 예제 2에서는 병렬로 실행되지 않고 작업 1이 실행되고 결과가 완료되면 주 스레드가 반환되어 작업 2를 시작합니다. - Maarten Kieft
  • @BlackHawkDesign : 아니요, 두 경우 모두실행하다동시에. 문제는 부모 메소드가기다리다동시에 또는 한 번에 하나씩. - Stephen Cleary
  • @ 스테판 클리어 리 : 당신이 의미하는 바를 봅니다, 당신 / servery가 옳습니다. 나는 두 번째 코드를 다음과 같이 해석했다. var task1 = GetList1Async ();를 기다린다. var task2 = GetList2Async ()를 기다립니다. 이 경우 그들은 서로 후에 처형 될 것입니다. 그러나 당신은 맞습니다.이 경우 그들은 둘 다 평행선에서 처형됩니다. - Maarten Kieft

1

첫 번째 구문은 더 읽기 쉽습니다. 결과를 얻기 전에 모든 작업이 완료되기를 기다리는 것이 좋습니다. 나는 그것을 두 번째 대신에 사용하는 것이 합리적이라고 생각한다.

또한 3 번째 또는 4 번째 작업을 추가하면 글을 더 적게 작성합니다 ... 나는. :

await Task.WhenAll(task1, task2, task3, task4);

비교 대상 :

var result1 = await task1; 
var result2 = await task2; 
var result3 = await task3; 
var result4 = await task4; 


  • 그러나 첫 번째 샘플에서는 어쨌든 모든 구성 작업을 기다리고 있습니다. 그 일을 피하고 반환 값을 사용하면 유일한 승리입니다.WhenAll대신. - Servy
  • 무엇이기 ' 이 경우 주관적으로 보인다. Task.WhenAll은 작업을 개별적으로 기다리는 것과 완전히 똑같지 않습니다 (Servy가 알고있는 것처럼). 보세요stackoverflow.com/q/18310996/1676558이 문제에 대해 더 자세히 배우고 싶다면 - user1676558

연결된 질문


관련된 질문

최근 질문