program story

task.Result?와 동일한 완료된 작업을 기다립니다.

inputbox 2020. 8. 15. 09:11
반응형

task.Result?와 동일한 완료된 작업을 기다립니다.


현재 Stephen Cleary의 " Concurrency in C # Cookbook "을 읽고 있는데 다음 기술을 발견했습니다.

var completedTask = await Task.WhenAny(downloadTask, timeoutTask);  
if (completedTask == timeoutTask)  
  return null;  
return await downloadTask;  

downloadTask호출이고 httpclient.GetStringAsync, 그리고 timeoutTask실행된다 Task.Delay.

시간 초과되지 않은 downloadTask경우 이미 완료된 것입니다. downloadTask.Result작업이 이미 완료된 경우 반환하는 대신 두 번째 대기를 수행해야하는 이유는 무엇 입니까?


여기에 이미 좋은 답변 / 댓글이 있지만 차임에 따라 ...

내가 (또는 ) await보다 선호하는 두 가지 이유가 있습니다 . 첫 번째는 오류 처리가 다르다는 것입니다. 예외를 . 이상적으로는 비동기 코드가 특별히 원하지 않는 한 전혀 처리 할 필요가 없어야 합니다.ResultWaitawaitAggregateExceptionAggregateException

두 번째 이유는 조금 더 미묘합니다. 내 블로그에 설명으로 (그리고 책) Result/ Wait교착 상태가 발생할 수에 사용하면 더욱 미묘한 교착 상태가 발생할 수 있습니다 async방법 . 내가 코드를 읽고 있어요 그리고 내가 볼 때, Result또는 Wait, 그 즉시 경고 플래그입니다. Result/는 Wait당신이 인 경우에만 정확한지 반드시 확인 작업이 이미 완료된다. (실제 코드에서) 한 눈에보기가 어려울뿐만 아니라 코드 변경에 더 취약합니다.

Result/ 사용 Wait해서는 안된다는아닙니다 . 내 코드에서 다음 지침을 따릅니다.

  1. 애플리케이션의 비동기 코드는 await.
  2. 비동기 유틸리티 코드 (라이브러리에 있음)는 코드에서 실제로 호출하는 경우 Result/를 사용할 수 있습니다 Wait. 그러한 사용법에는 아마도 주석이 있어야합니다.
  3. 병렬 작업 코드는 ResultWait.

(1)은 일반적인 경우이므로 await모든 곳 에서 사용 하고 다른 경우는 일반 규칙의 예외로 취급하는 경향이 있습니다 .


timeoutTask의 제품 이면 이치 Task.Delay에 맞습니다. 책에있는 내용을 믿습니다.

Task.WhenAny를 반환합니다 Task<Task>. 여기서 내부 작업은 인수로 전달한 작업 중 하나입니다. 다음과 같이 다시 작성할 수 있습니다.

Task<Task> anyTask = Task.WhenAny(downloadTask, timeoutTask);
await anyTask;
if (anyTask.Result == timeoutTask)  
  return null;  
return downloadTask.Result; 

두 경우 모두 downloadTask이미 완료 되었기 때문에 return await downloadTask사이에 아주 작은 차이가 return downloadTask.Result있습니다. AggregateException@KirillShlenskiy가 주석에서 지적했듯이 후자는 원래 예외를 래핑하는 throw됩니다 . 전자는 원래 예외를 다시 던질 것입니다.

두 경우 모두 예외를 처리 할 때마다 AggregateException내부 예외를 확인 하여 오류 원인을 찾아야합니다.

참고 URL : https://stackoverflow.com/questions/24623120/await-on-a-completed-task-same-as-task-result

반응형