当我们在代码中使用await时,通常等待者会捕获上下文,并在等待的任务成功完成时将其用作回调。但是,由于等待通常是一个No.Op(无操作),它是否使底层线程在等待任务执行完成之前不可重用?

例如

public async Task MethodAAsync()
{
     // Execute some logic
     var test = await MethodB();
    // Execute Remaining logic.
}


在这里,由于我需要返回结果以进一步进行操作,因此我需要等待。但是,由于我们正在等待,它是否会阻塞底层线程,导致线程不被用于执行任何任务?

最佳答案

但是,由于await通常是No.Op(无操作),它是否使
  在等待的任务执行之前,基础线程不可重用
  完成?


我不确定您从何处获得此信息,但是await肯定不是禁止操作。例如,在await上调用Task将调用对Task.GetAwaiter的逻辑调用,其中TaskAwaiter必须实现INotifyCompletionICriticalNotifyCompletion接口,这告诉编译器如何调用延续(第一个await之后的所有内容)。

async-await的完整结构将您的调用转换为状态机,以便当状态机命中第一个await时,它将首先检查以查看被调用的方法是否完成,如果未完成,则将注册延续并返回从该方法调用。稍后,该方法完成后,它将重新进入状态机以完成该方法。从逻辑上讲,这是您单击await后看到的行的方式。


  但是,由于我们正在等待,它是否会阻塞基础线程
  导致线程不被用来执行任何任务?


不,创建仅阻塞调用线程的完整机制将毫无用处。 async-await允许您实际将调用线程交还给调用方,这使他可以继续在同一线程上执行,而运行时负责排队和调用完成。

07-26 09:24
查看更多