C# 为什么AsyncTaskMethodBuilder在内部使用Task而不是TaskCompletionSource

C# 为什么AsyncTaskMethodBuilder在内部使用Task而不是TaskCompletionSource,c#,.net,C#,.net,当我们将一个方法标记为async并在内部使用Wait时,编译器将异步函数转换为状态机 比如说, private static async Task<String> MyMethodAsync(Int32 argument) { ... } 私有静态异步任务MyMethodAsync(Int32参数){…} 转化为 [DebuggerStepThrough, AsyncStateMachine(typeof(StateMachine))] private static Task&l

当我们将一个方法标记为async并在内部使用Wait时,编译器将异步函数转换为状态机 比如说,

private static async Task<String> MyMethodAsync(Int32 argument) { ... }
私有静态异步任务MyMethodAsync(Int32参数){…}
转化为

[DebuggerStepThrough, AsyncStateMachine(typeof(StateMachine))]
private static Task<String> MyMethodAsync(Int32 argument) {
   StateMachine stateMachine = new StateMachine() {
      m_builder = AsyncTaskMethodBuilder<String>.Create(),
      m_state = -1, // Initialize state machine location
      m_argument = argument // Copy arguments to state machine fields
   };

   // Start executing the state machine
   stateMachine.m_builder.Start(ref stateMachine);
   return stateMachine.m_builder.Task; // Return state machine's Task
}
[DebuggerStepThrough,AsyncStateMachine(typeof(StateMachine))]
私有静态任务MyMethodAsync(Int32参数){
StateMachine StateMachine=新的StateMachine(){
m_builder=AsyncTaskMethodBuilder.Create(),
m_state=-1,//初始化状态机位置
m_argument=参数//将参数复制到状态机字段
};
//开始执行状态机
stateMachine.m_builder.Start(参考stateMachine);
return stateMachine.m_builder.Task;//返回状态机的任务
}
AsyncTaskMethodBuilder的定义是

public struct AsyncTaskMethodBuilder<TResult> {
   private Task<TResult> m_task;
   ...

   public void SetResult(TResult result) {
      ... // call Task's TrySetResult method
   }
}
公共结构AsyncTaskMethodBuilder{ 私有任务m_任务; ... 公共void SetResult(TResult result){ …//调用任务的TrySetResult方法 } } 据我所知,TaskCompletionSource用于创建不执行代码的任务对象,这在状态机中是一个完美的例子,因为它创建了一个重新调谐到调用方的虚拟任务(
stateMachine.m_builder.Task
),一旦工作线程完成了原始任务,状态机将通过其
m_builder
成员调用SetResult,以手动将结果添加到虚拟任务中,那么为什么AsyncTaskMethodBuilder不使用TaskCompletionSource呢

为什么AsyncTaskMethodBuilder不使用TaskCompletionSource

任务
类型有许多内部API(仅对BCL可用)
AsyncTaskMethodBuilder
可以直接调用它们

TaskCompletionSource
用于完成承诺任务,如果BCL之外的任何人必须实现
AsyncTaskMethodBuilder
,那么他们必须使用TCS


换句话说:这是一个你我都无法使用的优化。

鉴于
TaskCompletionSource
是使用
Task
实现的,我认为这是为了避免在实现中使用额外的类。但是只有实现者才能真正回答这个问题。如果您查看
AsyncTaskMethodBuilder
的源代码,您会看到很多关于性能调优的评论。与使用通用类型相比,在这里使用可以精确调整以满足编译器需要的专用类型可能是更好的选择。