자신의 awaitable 형식 만 들 기
C \ # 5.0 에 await 키 워드 를 도입 하여 비동기 작업 을 쉽게 실현 할 수 있 습 니 다.대부분의 경우 await 는 보통 Task 와 함께 사용 하기에 도 편리 합 니 다.그러나 때로는 우리 자신의 awaitable 유형 을 사용자 정의 하여 더욱 높 은 유연성 과 효율 을 실현 해 야 한다.
await 연산 자 에 사용 할 대상 은 다음 과 같 습 니 다.
GetAwaiter () 방법 이나 확장 방법 이 있 습 니 다. 실현 되 었 습 니 다.
INotifyCompletion
인터페이스의 awaiter 대상 (또는 구조)
되 돌아 오 는 awaiter 대상 (또는 구조) 은 다음 과 같은 방법 을 요구 합 니 다.
void OnCompleted(Action continuation)
bool IsCompleted {get; }
TResultGetResult () / / TResult 도 void 형식 일 수 있 습 니 다.
다음은 await 연산 자가 어떻게 비동기 조작 을 실현 하 는 지 간단하게 소개 하 겠 습 니 다.
예 를 들 어 다음 코드 에 대해
var j = await 3; DoContinue(j);
컴 파일 할 때 컴 파일 러 에 의 해 다음 과 같은 절차 와 유사 한 코드 로 번역 된다.
var awaiter = 3.GetAwaiter(); var continuation = new Action(() => { var j = awaiter.GetResult(); DoContinue(j); }); if (awaiter.IsCompleted) continuation(); else awaiter.OnCompleted(continuation);
이 기초 가 있 으 면 우 리 는 int 형의 변수 에 대해 await 작업 을 실현 할 수 있 습 니 다.
class Program { staticvoid Main(string[] args) { Test(); Console.ReadLine(); } async static void Test() { var j = await 3; Console.WriteLine(j); } } class MyAwaiter : System.Runtime.CompilerServices.INotifyCompletion { public bool IsCompleted {get {returnfalse; } } public void OnCompleted(Action continuation) { Console.WriteLine("OnCompleted"); ThreadPool.QueueUserWorkItem(_ => { Thread.Sleep(1000); this.result = 300; continuation(); }); } int result; public int GetResult() { Console.WriteLine("GetResult"); return result; } } static class Extend { public static MyAwaiter GetAwaiter(thisint i) { return new MyAwaiter(); } }
이렇게 하면 await 가 어떻게 call / cc 식 비동기 작업 을 실현 하 는 지 알 수 있 습 니 다.
컴 파일 러 는 후속 작업 을 Action 대상 으로 패키지 합 니 다.
continuation
들어가다
awaiter 의
OnCompleted
함수 병렬 실행.
awaiter
OnCompleted
함수 에서 비동기 작업 을 수행 하고 비동기 작업 이 끝 난 후 (일반적으로 비동기 호출 의 리 셋 함수) 실 행 됩 니 다.
continuation
조작
continuation
작업 의 첫 번 째 단 계 는 awaiter. GetResult () 를 호출 하여 비동기 작업 의 반환 값 을 가 져 오고 후속 작업 을 계속 수행 하 는 것 입 니 다.
이 를 보면 여러분 들 이 await 의 메커니즘 에 대해 간단 한 인식 을 가지 게 되 었 다 고 믿 습 니 다. AsyncTargetingPack 이 왜. net 4.0 프로그램 도 await 작업 을 지원 하 는 지 이해 하기 어렵 지 않 습 니 다. 이 라 이브 러 리 는 AsyncCompatLib Extensions 류 에서 Task 류 에 GetAwaiter 확장 함 수 를 제공 합 니 다.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DoSomething();
}
public async Task DoSomething()
{
int test = 3;
await Sleep();
MessageBox.Show("Woke up!" + test.ToString());
}
internal MyTask Sleep()
{
return new MyTask();
}
public class MyTask
{
public MyAwaiter GetAwaiter()
{
return new MyAwaiter();
}
}
public class MyAwaiter : INotifyCompletion
{
public MyAwaiter()
{
}
public void OnCompleted(Action continuation)
{
new Thread(() =>
{
Thread.Sleep(3000);
continuation();
}
).Start();
}
public bool IsCompleted
{
get
{
return false;
}
}
public void GetResult()
{
}
}
}
}
C \ # Message Box. Show 를 continuation () 으로 봉 하여 OnComplete () 함수 에 전달 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.