먼저, "비동기"( async
) 라는 용어를 정리해 보자 . 에서 async
방법, 그 "수율"포인트는 await
표현은.
이것은 "백그라운드 스레드에서 실행"을 의미하기 위해 MSDN 문서에서 수년 동안 사용 된 "비동기"라는 용어와는 매우 다릅니다.
추가 async
로이 문제를 혼동시키기 위해 "대기 가능" 과 는 매우 다릅니다. async
반환 유형이 대기 할 수없는 일부 메소드와 대기하지 않는 유형을 리턴하는 많은 메소드가 있습니다 async
.
그들이 아닌 것에 대해 충분히 ; 여기에 그들이 무엇 있습니다 :
async
키워드는 (즉, 그것은 수있는 비동기 방식을 허용 await
표현). async
방법은 반환 할 수 있습니다 Task
, Task<T>
(당신이해야하는 경우), 또는 void
.
- 특정 패턴을 따르는 모든 유형을 기다릴 수 있습니다. 가장 일반적인 대기 유형은
Task
및 Task<T>
입니다.
따라서 귀하의 질문을 " 대기 가능한 방식으로 백그라운드 스레드 에서 작업 을 어떻게 실행할 수 있습니까?"로 재구성하면 대답은 다음과 Task.Run
같습니다.
private Task<int> DoWorkAsync() // No async because the method does not need await
{
return Task.Run(() =>
{
return 1 + 2;
});
}
그러나이 패턴은 좋지 않은 접근 방식입니다 (아래 참조).
그러나 귀하의 질문이 " async
차단하는 대신 호출자에게 되돌릴 수 있는 메소드를 작성하는 방법"인 경우, 메소드를 선언 하고 "수확"지점에 async
사용 하는 것이 답입니다 await
.
private async Task<int> GetWebPageHtmlSizeAsync()
{
var client = new HttpClient();
var html = await client.GetAsync("http://www.example.com/");
return html.Length;
}
따라서 기본적인 것의 패턴은 async
코드가 await
표현의 "대기 가능"에 의존 하도록하는 것입니다 . 이러한 "대기 가능 항목"은 다른 async
방법이거나 대기 가능 항목을 반환하는 일반적인 방법 일 수 있습니다 . 반환 정기 방법은 Task
/ Task<T>
수 사용하는 Task.Run
백그라운드 스레드에서 코드를 실행하거나 (더 일반적으로) 그들이 사용할 수 있습니다 TaskCompletionSource<T>
또는 바로 가기 (하나 TaskFactory.FromAsync
, Task.FromResult
등). 나는 하지 않는 전체 방법을 포장하는 것이 좋습니다 Task.Run
; 동기 메소드는 동기 서명을 가져야하며, 다음과 같이 랩핑되어야하는지 소비자에게 맡겨야합니다 Task.Run
.
private int DoWork()
{
return 1 + 2;
}
private void MoreSynchronousProcessing()
{
// Execute it directly (synchronously), since we are also a synchronous method.
var result = DoWork();
...
}
private async Task DoVariousThingsFromTheUIThreadAsync()
{
// I have a bunch of async work to do, and I am executed on the UI thread.
var result = await Task.Run(() => DoWork());
...
}
나는이 async
/ await
소개 내 블로그를; 마지막에는 좋은 후속 리소스가 있습니다. MSDN 문서 async
도 비정상적으로 좋습니다.