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.
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2017-07-15 Install the IIS 6.0 Management Compatibility Components in Windows 7 or in Windows Vista from Control Panel
2016-07-15 Task
2015-07-15 WCF 托管在IIS中遇到Http的错误
2015-07-15 Default Web Site
2015-07-15 Learning WCF Chapter1 Hosting a Service in IIS
2015-07-15 git subtree 拆分split repository