자신의 awaitable 형식 만 들 기

4093 단어
From: http://www.cnblogs.com/TianFang/archive/2012/09/21/2696769.html
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 () 함수 에 전달 합 니 다.

    좋은 웹페이지 즐겨찾기