가장 빠른 학습을 위해 ..
메소드 실행 플로우 이해 (다이어그램 사용) : 3 분
이 이미지에서 # 6에 집중하십시오 (아무것도 없습니다)
# 6 단계 : 실행이 부족하여 실행이 중지되었습니다. 계속하려면 getStringTask (종류의 함수)의 결과가 필요합니다. 따라서await
연산자를 진행 상황을 일시 중단하고 호출자에게 제어권을 부여합니다 (이 방법의). getStringTask에 대한 실제 호출은 2 번 초에 이루어졌습니다. # 2에서 문자열 결과를 반환하기로 약속했습니다. 그러나 결과는 언제 반환됩니까? 우리가 (# 1 : AccessTheWebAsync) 다시 전화를해야합니까? 결과를 얻는 사람, # 2 (호출 진술) 또는 # 6 (발언 대기)
AccessTheWebAsync ()의 외부 호출자도 지금 기다리고 있습니다. 따라서 호출자는 AccessTheWebAsync를 기다리고 있으며 AccessTheWebAsync는 현재 GetStringAsync를 기다리고 있습니다. 흥미로운 점은 AccessTheWebAsync가 대기 (# 4) 전에 대기에서 시간을 절약하기 위해 약간의 작업을 한 것입니다. 외부 발신자 (및 체인의 모든 발신자)에게도 멀티 태스킹에 대한 동일한 자유가 제공되며 이는 이 '비동기'기능의 가장 큰 장점입니다!동기 적이거나 정상적이라고 생각하지만 그렇지 않습니다.
메소드가 이미 리턴되었으므로 (# 2) 다시 리턴 할 수 없습니다 (두 번째는 아님). 그러면 발신자는 어떻게 알 수 있습니까? 작업 에 관한 모든 것입니다 ! 작업이 통과되었습니다. 작업이 기다렸습니다 (값이 아닌 방법이 아님). 작업에서 값이 설정됩니다. 작업 상태가 완료로 설정됩니다. 발신자는 작업 (# 6) 만 모니터링합니다. 6 #은 어디서 / 누가 결과를 얻는 지에 대한 답입니다. 자세한 내용은 여기를 참조하십시오 .
학습을위한 질문 내성 : 1 분
질문을 약간 조정 해 봅시다.
언제 어떻게 사용 하고 ? async
await
Tasks
학습 Task
은 다른 두 가지를 자동으로 다루기 때문에 (질문에 대한 답변)
구문 설탕을 빠르게 습득하십시오 : 5 분
변환 전 (원본 방법)
internal static int Method(int arg0, int arg1)
{
int result = arg0 + arg1;
IO(); // Do some long running IO.
return result;
}
위의 메서드를 호출하는 작업 기반 메서드
internal static Task<int> MethodTask(int arg0, int arg1)
{
Task<int> task = new Task<int>(() => Method(arg0, arg1));
task.Start(); // Hot task (started task) should always be returned.
return task;
}
우리는 대기 또는 비동기 언급 했습니까? 아니요. 위의 방법을 호출하면 모니터링 할 수있는 작업이 나타납니다. 작업이 무엇을 반환하는지 이미 알고 있습니다. 정수.
작업 호출은 약간 까다롭기 때문에 키워드가 나타나기 시작합니다. MethodTask ()를 호출하자
internal static async Task<int> MethodAsync(int arg0, int arg1)
{
int result = await HelperMethods.MethodTask(arg0, arg1);
return result;
}
위의 이미지와 동일한 코드가 아래 이미지에 추가되었습니다.
- 우리는 작업을 끝내기를 기다리고 있습니다. 따라서
await
- await를 사용하기 때문에 반드시 사용해야합니다
async
(필수 구문).
Async
접두사로 사용하는 MethodAsync (코딩 표준)
await
이해하기 쉽지만 나머지 두 개 ( async
, Async
)는 :)가 아닐 수 있습니다. 그래도 컴파일러에게는 훨씬 더 합리적이어야 합니다.
두 부분이 있습니다.
- '작업'만들기
- 작업을 호출하는 구문 설탕 만들기 (
await+async
)
우리는 AccessTheWebAsync ()에 대한 외부 호출자를 가지고 있었고 그 호출자는 절약되지 않았습니다. 즉, 같은 await+async
것도 필요합니다 . 그리고 체인은 계속됩니다. 그러나 항상 Task
한쪽 끝에 있을 것 입니다.
괜찮습니다.하지만 한 개발자가 # 1 (작업)이 누락 된 것을보고 놀랐습니다 ...
개발자의 혼란을 공유하십시오 : 5 분
개발자가 구현하지 않은 실수를 Task
했지만 여전히 작동합니다! 여기에 제공된 질문과 허용 된 답변 만 이해 하십시오 . 당신이 읽고 완전히 이해하기를 바랍니다. 요약하면 '작업'을 보거나 구현하지 못할 수도 있지만 부모 클래스 어딘가에 구현되어 있습니다. 마찬가지로이 예제에서 이미 빌드 된 호출은 ( ) ourself로 MethodAsync()
해당 메소드를 구현하는 것보다 훨씬 쉽습니다 . 대부분의 개발자 는 코드를 비동기 코드로 변환하는 동안 어려움을 겪고 있습니다.Task
MethodTask()
Tasks
팁 : 기존 비동기 구현 ( MethodAsync
또는 같은 ToListAsync
)을 찾아서 어려움을 아웃소싱하십시오. 따라서 Async 만 처리하면됩니다 (일반 코드와 쉽고 유사 함).
문제 : 실제 코드의 실제 구현을 비동기 작업으로 빠르게 변경 : 2 분
아래의 데이터 레이어에 표시된 코드 줄이 깨지기 시작했습니다 (많은 곳). 코드 일부를 .Net framework 4.2. *에서 .Net 코어로 업데이트했기 때문입니다. 애플리케이션 전체에서 1 시간 안에이 문제를 해결해야했습니다!
var myContract = query.Where(c => c.ContractID == _contractID).First();
쉬워요!
- QueryableExtensions가 있기 때문에 EntityFramework nuget 패키지를 설치했습니다. 즉, 그것은 비동기 구현 (태스크)을 수행하므로 단순
Async
하고 await
코드로 살아남을 수 있습니다.
- 네임 스페이스 = Microsoft.EntityFrameworkCore
호출 코드 줄이 이렇게 변경되었습니다.
var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
메소드 서명이
Contract GetContract(int contractnumber)
에
async Task<Contract> GetContractAsync(int contractnumber)
호출하는 방법도 영향을 받았습니다 : GetContractAsync(123456);
로 불렀다GetContractAsync(123456).Result;
우리는 그것을 30 분 만에 모든 곳에서 바 꾸었습니다!
그러나 건축가는 이것을 위해 EntityFramework 라이브러리를 사용하지 말라고 말했습니다! 죄송합니다! 드라마! 그런 다음 맞춤 작업 구현 (yuk)을 만들었습니다. 당신은 어떻게 알고 있습니다. 아직도 쉬워요! .. 아직도 ..
다음에 어디? ASP.Net Core에서 동기 호출을 비동기로 변환
에 대해 볼 수있는 멋진 비디오가 있습니다 . 아마도 이것을 읽은 후 갈 방향 일 것입니다.