首页 > 解决方案 > 真的需要'async/await all the way up'吗

问题描述

我熟悉异步/等待,使用异步函数在等待时将线程返回到池中。我可以在为另一个 API 请求返回线程的控制器方法中以及在任何第 3 方 API 调用(例如 AWS)中看到这一点的好处。

但是在整个调用堆栈中使用它有什么好处吗?考虑这个伪代码示例:

public class MyController
    public async Task<IActionResult> MyFirstFunction()
    {
        var result = await _myHandler.MySecondFunction();
        ...
        return Ok();
    }
}

public class MyHandler
    public Task<bool> MySecondFunction()
    {
        ...
        return thirdPartyHandler.ThirdPartyFunction(object);
    }
}

public class ThirdPartyHandler
    public async Task<bool> ThirdPartyFunction(Object object)
    {
        return await thirdParty.ExternalFunctionAsync(object);
    }
}

这段代码不会实现与使“MySecondFunction”函数异步并等待ThirdPartyFunction() 函数调用相同的事情,而不必处理捕获上下文并将线程返回到池等的开销更少吗?

诚然 MyHandler 和 ThirdPartyHandler 有点多余,可以组合

标签: .netasync-awaitcallstack

解决方案


我熟悉异步/等待,使用异步函数在等待时将线程返回到池中。

这不是/的工作方式asyncawaitawait只是返回给它的调用者。它不会立即将线程返回到线程池。在 ASP.NET 场景中,awaits 的行为就像正常一样,一直返回到控制器操作。当控制器操作执行一个await时,它将返回到 ASP.NET 运行时,这实际上是将线程返回到线程池。

要记住的另一件有用的事情是这段代码:

var result = await MyFunctionAsync();

大致相当于这段代码:

var task = MyFunctionAsync();
var result = await task;

换句话说,首先同步调用该方法。当MyFunctionAsync点击一个await并且需要让步时,它将返回一个不完整的任务。然后这个函数等待那个任务——如果它需要让步,它会返回一个不完整的任务给它的调用者,等等。这里没有线程切换——只是在一个正常的调用堆栈上返回值。

所以,await一路使用不会破坏你的表现。这就是它的设计用途。


public Task<bool> MySecondFunction()
{
  ...
  return thirdPartyHandler.ThirdPartyFunction(object);
}

这段代码不会实现与使“MySecondFunction”函数异步并等待ThirdPartyFunction() 函数调用相同的事情,而不必处理捕获上下文并将线程返回到池等的开销更少吗?

可能不是。消除asyncawait有许多陷阱。除非该...函数中的 in 确实微不足道,否则您将希望保留asyncandawait关键字。开销是最小的。


推荐阅读