이 질문과 비슷하게 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}");
}
}
}
간단하게 대답하기 어려운 부분도 있네요. 먼저, async/await 에 대해 심도있게 개념을 파악해 보시는것을 먼저 추천을 드립니다.
질문에 대한 간략한 답은,
await는 비동기 대기,
Task의 Result는 동기 대기를 하게 됩니다.
비동기 메소드는 결과 값을 얻기까지의 소요시간이 예상할수 없거나, 오래 걸리는 작업에 사용하면 유용하다고 보시면 됩니다. 그러므로 Result보다는 await로 정확히 비동기 대기로 기다리시는것을 권합니다.
동작도 상이합니다. await의 경우 결과 값을 받기 까지 대기하는것은 Result와 동일하지만, 스레드 상태가 달라집니다. await로 인해 값을 받기까지의 대기는, 진입 스레드에 있지 않습니다. 이 동작을 확실하게 눈으로 확인하시려면 Windows Forms이나 WPF 등 UI에서 비동기 메소드를 호출해 보시면 됩니다.
Result의 경우 호출 스레드가 값이 반환될 때까지 대기하는데 반해, await로 비동기 대기하는 경우, 호출 스레드는 자신의 스레드 흐름으로 넘어가 화면이 계속적으로 반응합니다.
링크들 가운데 내용이 있을 수 있겠으나, 댓글을 통한 동기화컨텍스트에 관한 내용이 직접적인 언급이 없어서 남깁니다.
Result를 작업하는 것은 위에서 여러 유저분들이 잘 설명해주신대로 동기방식으로 결과를 가져오고, await으로 하면 비동기로 값을 가져옵니다.
다만 SangHyeon.Kim님께서 말씀하신대로 데드락에 걸릴 수 있습니다.
ConsoleApp은 동기화 컨텍스트가 null 이기 때문에 Result와 await의 결과가 같고 데드락도 걸리지 않습니다.
반면 winform/wpf/aspnetcore는 각자 스스로만의 동기화 컨텍스트가 존재하는데, 그런 이유로 데드락이 발생하며, 아래 정성태님 블로그에서 자세히 설명해주시고 계십니다.