최근에 많은 비동기 메소드를 사용하는 코드를 읽었지만 때로는 동기식으로 실행해야합니다. 코드는 다음을 수행합니다.
Foo foo = GetFooAsync(...).GetAwaiter().GetResult();
이것과 동일합니까
Foo foo = GetFooAsync(...).Result;
답변
거의 요 한 가지 작은 차이점 : Task
실패하면 GetResult()
직접 발생한 예외 Task.Result
를 throw하고을 throw합니다 AggregateException
. 그러나 어느 때에 사용하는 것이 중요 async
합니까? 100 배 더 나은 옵션은을 사용하는 것 await
입니다.
또한을 사용하지 마십시오 GetResult()
. 이것은 컴파일러가 아닌 사용자를위한 것입니다. 그러나 성가신 것을 원하지 않으면 AggregateException
사용하십시오.
답변
Task.GetAwaiter().GetResult()
이상 선호 Task.Wait
하고 Task.Result
그것은 그들을 포장보다는 예외를 전파하기 때문에 AggregateException
. 그러나 세 가지 방법 모두 교착 상태 및 스레드 풀 기아 문제가 발생할 수 있습니다. 그들은 모두 찬성하여 피해야한다 async/await
.
아래 인용하는 이유를 설명 Task.Wait
하고 Task.Result
단지의 예외 전파 동작을 포함하지 않는 Task.GetAwaiter().GetResult()
(인해 “매우 높은 호환성 바”로).
앞에서 언급했듯이 호환성이 매우 높기 때문에 변경 사항을 피할 수 있습니다. 따라서
Task.Wait
항상 줄 바꿈의 원래 동작을 유지합니다. 그러나에 의해 사용되는 동기식 차단과 유사한 동작을 원Task.Wait
하지만 원래 예외가에 포함되지 않고 래핑되지 않은 전파를 원하는 일부 고급 상황에 처할 수 있습니다AggregateException
. 이를 위해 작업 대기자를 직접 대상으로 지정할 수 있습니다. ”await task;
” 를 쓰면 컴파일러는이를Task.GetAwaiter()
메서드의 사용법으로 변환하여 메서드가있는 인스턴스를 반환합니다GetResult()
. 결함이있는 작업에 사용될GetResult()
경우 원래 예외를 전파합니다 ( ”await task;
“의 동작 방식). 따라서 “task.GetAwaiter().GetResult()
이 전파 로직을 직접 호출하려는 경우
https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/
“
GetResult
”은 실제로“작업에 오류가 있는지 확인”을 의미합니다일반적으로 비동기 작업을 동 기적으로 차단하지 않으려 고 최선을 다합니다. 그러나 그 지침을 위반하는 몇 가지 상황이 있습니다. 드문 조건에서 내가 선호하는 방법은
GetAwaiter().GetResult()
작업 예외를에 감싸는 대신 보존하기 때문AggregateException
입니다.
http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html
답변
https://github.com/aspnet/Security/issues/59
“마지막 말 : 당신은 사용하지 않아야
Task.Result
하고Task.Wait
가능한 한 그들은 항상에서 내부 예외를 캡슐화로
AggregateException
더 열심히 디버깅하게 일반적인 하나 (하나 이상의 오류가 발생)에 의해 메시지를 교체하더라도 동기 버전 shouldn. 자주 사용Task.GetAwaiter().GetResult()
하지 말고 대신 사용하는 것이 좋습니다. “
답변
또 다른 차이점은 async
함수 Task
대신에 함수가 반환 되면 Task<T>
사용할 수 없다는 것입니다
GetFooAsync(...).Result;
이므로
GetFooAsync(...).GetAwaiter().GetResult();
여전히 작동합니다.
질문의 예제 코드가 사례임을 알고 Task<T>
있지만 질문은 일반적으로 요구됩니다.
답변
이미 언급했듯이을 사용할 수 있습니다 await
. 당신은 당신이 언급처럼 기적으로 코드를 실행해야하는 경우 .GetAwaiter().GetResult()
, .Result
또는 .Wait()
교착 상태의 위험이다 많은 사람들이 의견 / 답변에서 말했듯이. 우리 대부분은 oneliners를 좋아하기 때문에 이것을 사용할 수 있습니다.Net 4.5<
비동기 메서드를 통해 값을 얻는 방법 :
var result = Task.Run(() => asyncGetValue()).Result;
비동기 메서드를 동 기적으로 호출
Task.Run(() => asyncMethod()).Wait();
사용으로 인해 교착 상태 문제가 발생하지 않습니다 Task.Run
.
출처:
답변
작업에 오류가 발생하면 연속 코드가 awaiter.GetResult ()를 호출 할 때 예외가 다시 발생합니다. GetResult를 호출하는 대신 작업의 Result 속성에 간단히 액세스 할 수 있습니다. GetResult 호출의 이점은 작업이 실패하면 AggregateException에 래핑되지 않고 예외가 직접 발생하여 더 간단하고 깔끔한 catch 블록을 허용한다는 것입니다.
제네릭이 아닌 작업의 경우 GetResult ()에는 void 반환 값이 있습니다. 유용한 기능은 전적으로 예외를 다시 발생시키는 것입니다.
출처 : 간단히 말해서 c # 7.0
답변
![](http://daplus.net/wp-content/uploads/2023/04/coupang_part-e1630022808943-2.png)