zoukankan      html  css  js  c++  java
  • Async Task Types in C#

    Async Task Types in C#

    Extend async to support task types that match a specific pattern, in addition to the well known types System.Threading.Tasks.Task and System.Threading.Tasks.Task<T>.

     

    Task Type

    A task type is a class or struct with an associated builder type identified with System.Runtime.CompilerServices.AsyncMethodBuilderAttribute. The task type may be non-generic, for async methods that do not return a value, or generic, for methods that return a value.

    To support await, the task type must have a corresponding, accessible GetAwaiter() method that returns an instance of an awaiter type (see C# 7.7.7.1 Awaitable expressions).

    [AsyncMethodBuilder(typeof(MyTaskMethodBuilder<>))]
    class MyTask<T>
    {
        public Awaiter<T> GetAwaiter();
    }
    
    class Awaiter<T> : INotifyCompletion
    {
        public bool IsCompleted { get; }
        public T GetResult();
        public void OnCompleted(Action completion);
    }
    

     

    Builder Type

    The builder type is a class or struct that corresponds to the specific task type. The builder type has the following public methods. For non-generic builder types, SetResult() has no parameters.

    class MyTaskMethodBuilder<T>
    {
        public static MyTaskMethodBuilder<T> Create();
    
        public void Start<TStateMachine>(ref TStateMachine stateMachine)
            where TStateMachine : IAsyncStateMachine;
    
        public void SetStateMachine(IAsyncStateMachine stateMachine);
        public void SetException(Exception exception);
        public void SetResult(T result);
    
        public void AwaitOnCompleted<TAwaiter, TStateMachine>(
            ref TAwaiter awaiter, ref TStateMachine stateMachine)
            where TAwaiter : INotifyCompletion
            where TStateMachine : IAsyncStateMachine;
        public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
            ref TAwaiter awaiter, ref TStateMachine stateMachine)
            where TAwaiter : ICriticalNotifyCompletion
            where TStateMachine : IAsyncStateMachine;
    
        public MyTask<T> Task { get; }
    }
    

     

    Execution

    The types above are used by the compiler to generate the code for the state machine of an async method. (The generated code is equivalent to the code generated for async methods that return Task, Task<T>, or void. The difference is, for those well known types, the builder types are also known to the compiler.)

    Builder.Create() is invoked to create an instance of the builder type.

    If the state machine is implemented as a struct, then builder.SetStateMachine(stateMachine) is called with a boxed instance of the state machine that the builder can cache if necessary.

    builder.Start(ref stateMachine) is invoked to associate the builder with compiler-generated state machine instance. The builder must call stateMachine.MoveNext() either in Start() or after Start() has returned to advance the state machine. After Start() returns, the async method calls builder.Task for the task to return from the async method.

    Each call to stateMachine.MoveNext() will advance the state machine. If the state machine completes successfully, builder.SetResult() is called, with the method return value if any. If an exception is thrown in the state machine, builder.SetException(exception) is called.

    If the state machine reaches an await expr expression, expr.GetAwaiter() is invoked. If the awaiter implements ICriticalNotifyCompletion and IsCompleted is false, the state machine invokes builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine). AwaitUnsafeOnCompleted() should call awaiter.OnCompleted(action) with an action that calls stateMachine.MoveNext() when the awaiter completes. Similarly for INotifyCompletion and builder.AwaitOnCompleted().

     

    Overload Resolution

    Overload resolution is extended to recognize task types in addition to Task and Task<T>.

    An async lambda with no return value is an exact match for an overload candidate parameter of non-generic task type, and an async lambda with return type T is an exact match for an overload candidate parameter of generic task type.

    Otherwise if an async lambda is not an exact match for either of two candidate parameters of task types, or an exact match for both, and there is an implicit conversion from one candidate type to the other, the from candidate wins. Otherwise recursively evaluate the types A and B within Task1<A> and Task2<B> for better match.

    Otherwise if an async lambda is not an exact match for either of two candidate parameters of task types, but one candidate is a more specialized type than the other, the more specialized candidate wins.

  • 相关阅读:
    Java 读取txt文件,读取结果保存到数据库
    Java 读取大文件方法
    利用File类过滤器列出目录下的指定目录或文件
    Java 读取指定目录下的文件名和目录名
    利用js日期控件重构WEB功能
    简洁js日历控件的使用
    Tomcat中配置URIEncoding="UTF-8"来处理中文的方法
    Java MVC 增删改查 实例
    严重:The web application [web01] appears to have started a thread named ...
    警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} 解决方法
  • 原文地址:https://www.cnblogs.com/chucklu/p/11187884.html
Copyright © 2011-2022 走看看