Await 와 result의 차이 질문

c# - Await vs Task.Result in an Async Method - Stack Overflow

c# - How does Task become an int? - Stack Overflow

이 질문과 비슷하게 async task에서 await와 그냥 void에서 task.result의 차이를 위 링크에서 읽어봤는데 잘 이해가 되지 않아 질문드립니다.

      public async Task<bool> POSTDataTaskAsync(object json, string url)
      {
         using (var content = new StringContent(JsonConvert.SerializeObject(json), System.Text.Encoding.UTF8, "application/json"))
         {
            using (HttpResponseMessage result = await httpClient.PostAsync(url, content))
            {
               if (result.StatusCode.Equals(HttpStatusCode.Created))
                  return true;

               string returnValue = await result.Content.ReadAsStringAsync();
               throw new Exception($"Failed to POST data: ({result.StatusCode}): {returnValue}");
            }
         }
      }

      public bool POSTDataAsync(object json, string url)
      {
         using (var content = new StringContent(JsonConvert.SerializeObject(json), System.Text.Encoding.UTF8, "application/json"))
         {
            using (HttpResponseMessage result = httpClient.PostAsync(url, content).Result)
            {
               if (result.StatusCode.Equals(HttpStatusCode.Created))
                  return true;

               string returnValue = result.Content.ReadAsStringAsync().Result;
               throw new Exception($"Failed to POST data: ({result.StatusCode}): {returnValue}");
            }
         }
      }

차이와 rest api get, post, put을 사용할 때 어떤 방법이 조금 더 좋은지 알 수 있을까요??

3개의 좋아요

간단하게 대답하기 어려운 부분도 있네요. 먼저, async/await 에 대해 심도있게 개념을 파악해 보시는것을 먼저 추천을 드립니다.

질문에 대한 간략한 답은,

await는 비동기 대기,

Task의 Result는 동기 대기를 하게 됩니다.

비동기 메소드는 결과 값을 얻기까지의 소요시간이 예상할수 없거나, 오래 걸리는 작업에 사용하면 유용하다고 보시면 됩니다. 그러므로 Result보다는 await로 정확히 비동기 대기로 기다리시는것을 권합니다.

동작도 상이합니다. await의 경우 결과 값을 받기 까지 대기하는것은 Result와 동일하지만, 스레드 상태가 달라집니다. await로 인해 값을 받기까지의 대기는, 진입 스레드에 있지 않습니다. 이 동작을 확실하게 눈으로 확인하시려면 Windows Forms이나 WPF 등 UI에서 비동기 메소드를 호출해 보시면 됩니다.

Result의 경우 호출 스레드가 값이 반환될 때까지 대기하는데 반해, await로 비동기 대기하는 경우, 호출 스레드는 자신의 스레드 흐름으로 넘어가 화면이 계속적으로 반응합니다.

4개의 좋아요

아래 글의 도식을 참고하시면 좋겠네요. (물론, UI 스레드로 복귀하는 것은 async/await 특징이 아니라 SynchronizationContext로 인해 UI Thread로 복귀하게 됩니다)

Async and Await - Here be dragons.md (github.com)

4개의 좋아요

Result 보다는 async/await를 사용한 비동기 대기를 하는게 좋습니다.
이쪽이 감이 잘 안온다면 영어이긴 하지만 번역기를 써서라도 아래 글을 참고하면 좋을 것 같아요.

이 글은 async/await 또는 Task.Result 사용에 대해 BAD/GOOD 케이스로 구분해 설명하고 있습니다.

저도 한번씩 긴가민가할 때 이곳의 도움을 받고 있습니다 :slightly_smiling_face:

5개의 좋아요

모두 답변 감사드립니다!!
천천히 읽어보겠습니다:grinning:

3개의 좋아요

다른분들이 좋은 답변들 달아주셨네요!
여담으로 하나 이야기 남기고 가자면…
.Net 의 Task 처음 접하시는분들이 Task.Result 썼다가 데드락에 빠지는 경우 심심찮게 볼 수 있었습니다!

그냥 일반적인 동기 로직과 Task.Result 동기 방식의 동작 차이를 알아두면 좋은것 같습니다!

4개의 좋아요

이 글도 꼭 읽어보시기를 추천드립니다.

문제가 발생하면 디버깅해보는 것이 맞지만, deadlock을 예방하기 위한 기본적인 패턴으로 제가 즐겨 쓰는 방법은 다음과 같습니다.

  • async/await을 부르는 호출 관계도 상 가장 상단의 소비자 영역 (consumer) 단계에서는 .ConfigureAwait(false)를 부르지 않습니다.
  • 반면 라이브러리나 다른 async/await 컨슈머에서 사용하게 될 여지가 있는 코드 단계에서는 .ConfigureAwait(false)를 부르도록 코드를 작성합니다.
5개의 좋아요

답변 감사드립니다!!!
아무것도 모르고 혼용해서 썼었는데 알고 가게 되네요 ㅎㅎ

3개의 좋아요

답변 감사드립니다 ㅎㅎ!
많이 알고 가네요!

3개의 좋아요

여담이지만…
뭔가 빌게이츠 닮으셨네요… 짱…

4개의 좋아요

앜ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 그런가요…

2개의 좋아요

@tjdskaqks 제게도 필요한 질몬인데 감사합니다. :smile:

2개의 좋아요

링크들 가운데 내용이 있을 수 있겠으나, 댓글을 통한 동기화컨텍스트에 관한 내용이 직접적인 언급이 없어서 남깁니다.

Result를 작업하는 것은 위에서 여러 유저분들이 잘 설명해주신대로 동기방식으로 결과를 가져오고, await으로 하면 비동기로 값을 가져옵니다.
다만 SangHyeon.Kim님께서 말씀하신대로 데드락에 걸릴 수 있습니다.
ConsoleApp은 동기화 컨텍스트가 null 이기 때문에 Result와 await의 결과가 같고 데드락도 걸리지 않습니다.
반면 winform/wpf/aspnetcore는 각자 스스로만의 동기화 컨텍스트가 존재하는데, 그런 이유로 데드락이 발생하며, 아래 정성태님 블로그에서 자세히 설명해주시고 계십니다.

https://www.sysnet.pe.kr/2/0/1541

4개의 좋아요