【问题标题】:why AsyncTaskMethodBuilder use Task internally instead of TaskCompletionSource为什么 AsyncTaskMethodBuilder 在内部使用 Task 而不是 TaskCompletionSource
【发布时间】:2021-05-26 19:26:23
【问题描述】:

当我们将方法标记为 async 并在 Compiler 中使用 await 时,会将 async 函数转换为状态机 例如,

private static async Task<String> MyMethodAsync(Int32 argument) { ... }

变身

[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
}

而AsyncTaskMethodBuilder的定义是

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

   public void SetResult(TResult result) {
      ... // call Task's TrySetResult method
   }
}

据我所知,TaskCompletionSource 用于创建不执行代码的任务对象,这是状态机中的完美案例,因为它创建了一个虚拟任务 (stateMachine.m_builder.Task) 重新调整给调用者,并且一旦工作线程完成原始任务后,状态机会通过其m_builder成员调用SetResult手动将结果添加到虚拟任务中,那么为什么AsyncTaskMethodBuilder不使用TaskCompletionSource呢?

【问题讨论】:

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

标签: c# .net


【解决方案1】:

为什么 AsyncTaskMethodBuilder 不使用 TaskCompletionSource?

Task 类型具有许多内部 API(仅适用于 BCL)。 AsyncTaskMethodBuilder 可以直接打电话给他们。

TaskCompletionSource&lt;T&gt; 用于完成 Promise 任务,如果 BCL 之外的任何其他人必须实现 AsyncTaskMethodBuilder,那么他们必须使用 TCS。

换句话说:这是一种优化,您或我都无法使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    • 2015-09-06
    • 2014-10-30
    • 2014-02-10
    • 2015-05-29
    • 2017-10-13
    • 2017-11-06
    相关资源
    最近更新 更多