2016-10-21 2 views
3

async 메서드에서 을 호출하면 교착 상태가 발생할 수 있다는 것을 알고 있습니다. 그래도 질문에 다른 비틀어 짐.작업 완료를 알면 비동기 메서드로 task.Result를 호출해도 괜찮습니까?

나는이 패턴을 많이하고 있음을 알았다. 같은 유형의 결과를 반환하는 여러 가지 작업이 있으므로 한 번에 모두 기다릴 수 있습니다. 그래도, 개별적으로 결과를 처리 할 :

Task<int> t1 = m1Async(); 
Task<int> t2 = m2Async(); 
await Task.WhenAll(t1, t2); 

그것이 내가 알고 있기 때문에 작업이 현재 완료, 여기 Result 전화를 확인인가? 난 아직도 await를 사용해야합니다

int result1 = t1.Result; 
int result2 = t2.Result; 

또는은 ... 그냥 중복 보인다 나는 결과를 처리 할 방법에 따라 약간의 추악한 될 수 있습니다

int result1 = await t1; 
int result2 = await t2; 

업데이트 : 누군가가 내 질문을 표시 이 사본으로 복제본 : Awaiting multiple Tasks with different results. 질문이 다르므로 내 검색에서 찾지 못했습니다. 거기에 대한 자세한 대답 중 하나가 질문 할 수도 있습니다.

+1

네, 알고 있다면 Result를 호출해도됩니다. 그러나 WhenAll과 t1 또는 t2가 예외를 던진 후에 .Result를 호출하면 .Result가 문제가 될 수 있습니다. –

+0

예외가있는 다른 동작을 나타내는 게시물을 보았습니다.하지만이 모든 것을 이해하려면 좀 더 자세히 조사해야합니다. 빠른 응답에 감사드립니다! – Cary

+0

알아 두어야 할 것이 하나 있습니다. 이미 완료된 상태의 작업에'await'을 호출하면 성능 오버 헤드가 0입니다. 상태 머신은 생성 된 상태를 검사하고 기본적으로'.Result'를 내부적으로 호출하는 것으로 건너 뜁니다. (실제로'.GetAwaiter(). GetResult()'를 호출하지만,'.Result'를 호출하는 것과 동일한 오버 헤드를가집니다.). 그래서 나에게 이미'async'라고 표시된 메소드 안에서'.Result'를 사용하는 강력한 이유는 없습니다. –

답변

5

이미 await을 작성한 후에 t1.Result을 사용하는 데 본질적으로 잘못되거나 불만이 없지만 향후 문제가 될 수 있습니다. 메소드가 시작될 때 누군가가 코드를 변경하여 더 이상 태스크가 성공적으로 완료되지 못하면 어떻게합니까? 그리고 만약 여러분의 코드가이 가정을 더 이상 보이지 않는다면 어떻게 될까요?

첫 번째 await에서 반환 된 값을 사용하는 것이 나을 것 같습니다. 누군가가 처음 await 놨어요 경우

Task<int> t1 = m1Async(); 
Task<int> t2 = m2Async(); 
var results = await Task.WhenAll(t1, t2); 

int result1 = results[0]; 
int result2 = results[1]; 

그 방법은, 그들이 당신의 코드가 나중에 그 결과에 의존 알고 따를에 대한 자연적인 연결이있다.

Task.WhenAll()이 실제로 여기에 가치를 부여하는지 여부를 고려해 볼 수 있습니다. 실패한 작업과 실패한 작업의 차이점을 밝히기를 원하지 않는다면 작업을 개별적으로 기다리는 것이 간단 할 수도 있습니다.

Task<int> t1 = m1Async(); 
Task<int> t2 = m2Async(); 

int result1 = await t1; 
int result2 = await t2; 
+0

WhenAll의 반환을 사용한 좋은 점. 그것은 더 복잡한 시나리오에서 결과를 정렬하기 위해 털이 얻을 수 있습니다. 그리고 개별적으로 작업을 기다리는 경우에는 통화를 직렬화하지 않습니까? – Cary

+2

@Cary : 다른 호출을하기 전에 첫 번째 호출을 기다리는 경우에만 호출을 직렬화합니다. m1Async()에서 결과를 기다리기 전에'm2Async()'를 호출하면 실행이 범위를 벗어나기 전에 두 번째 호출이 진행됩니다. – StriplingWarrior

0

기타 문서는 Task.Resultit is equivalent to calling the Wait method을 말한다.

그리고 Wait

를 호출 할 때 "Task.Wait은 무엇입니까?"

... 작업이 완료 실행 한 경우, 성공적으로 반환합니다 기다립니다.

(https://blogs.msdn.microsoft.com/pfxteam/2009/10/15/task-wait-and-inlining/에서)

그래서 당신은 당신이 Task.Result를 호출 할 때, 성공적 당신이 언급 한 교착 상태에 이르는하지 반환 것이라고 가정 할 수있다.

관련 문제