Jon Skeet의 "C # in depth. 3rd edition"에서 다음 예제를 찾았습니다.
static async Task<int> GetPageLengthAsync(string url)
{
using (HttpClient client = new HttpClient())
{
Task<string> fetchTextTask = client.GetStringAsync(url);
int length = (await fetchTextTask).Length;
return length;
}
}
public static void Main()
{
Task<int> lengthTask = GetPageLengthAsync("http://csharpindepth.com");
Console.WriteLine(lengthTask.Result);
}
이 코드가 교착 상태가 될 것으로 예상했지만 그렇지 않습니다.
내가보기에 다음과 같이 작동합니다.
Main
메서드 GetPageLengthAsync
는 메인 스레드 내에서 동 기적으로 호출 됩니다.GetPageLengthAsync
비동기 요청 즉시 반환한다 Task<int>
에 Main
"잠시 동안 대기, 나는 두 번째 당신에게 int를 반환합니다"라고.Main
실행을 계속하고 비틀 거리며 lengthTask.Result
메인 스레드가 차단되고 lengthTask
작업이 완료 되기를 기다립니다 .GetStringAsync
메인 스레드가 실행 Length
되고 계속을 시작할 수있게 될 때까지 완료하고 기다립니다 .하지만 내가 뭔가를 오해하는 것 같습니다. 이 코드가 교착 상태가 아닌 이유는 무엇입니까?
대기 / 비동기 교착 상태에 대한이 StackOverflow 질문 의 코드 는 동일한 작업을 수행하는 것처럼 보이지만 교착 상태입니다.
await
UI 스레드 (데스크톱 UI 응용 프로그램의 경우)이든 ASP.NET의 요청 컨텍스트 (코어가 아님)이든 원래 동기화 컨텍스트로 돌아갑니다.
GUI 애플리케이션에서는 UI 스레드가 .Result
. await
이 호출이 끝날 때까지 영원히 기다릴 것입니다.
콘솔 애플리케이션과 ASP.NET Core에는 동기화 컨텍스트가 없으므로 호출시 .Result
교착 상태가 발생하지 않습니다.
VS 15.3 용 PS :
Visual Studio 2017 15.3 Preview 2 (gasp)는 비동기 메인 애플리케이션을 허용합니다. 그것으로 다음과 같이 쓸 수 있습니다.
public static Task Main()
{
var length = await GetPageLengthAsync("http://csharpindepth.com");
Console.WriteLine(length);
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다