我们有许多使用 await
/async
关键字的异步 Controller 和服务。
一些 Action 看起来有点像:
public async Task<SomeViewModel> Get(int id)
{
var someData = await _service.GetData(id);
var someOtherData = await _service.GetMoreData(id);
return new SomeViewModel
{
Data = someData,
OtherData = someOtherData,
}
}
可能是服务调用本身也有多个 await
。 await
通常针对 Entity Framework 、服务总线或第 3 方网络端点的 async
调用。
我的一位同事今天提出这种代码毫无意义,它只会为线程管理产生额外的工作,而在负载不足的情况下,我们实际上会为运行时产生更多的工作并减慢应用程序结果下降。
他们是对的吗?如果是的话,当您在 Web API 请求中有多个 IO 绑定(bind)调用时,async
/await
的最佳实践是什么?
最佳答案
One of my colleagues came to be today suggesting that this kind of code was pointless, that it would simply generate extra work for thread management and the under load we would be actually generate more work for the for the runtime and slow the app down as a result.
这很有趣,因为事实恰恰相反。正如其他回答者所指出的那样,如果您使用的是真正的异步操作(即,不是 Task.Run
或类似的东西),那么使用的线程更少并且应用程序在负载下响应更好。
有些人(不是我)对“普通”ASP.NET 应用程序转换为 async
进行了研究,他们发现在转换为 async
时可扩展性提高了 10 到 100 倍code> 而不是阻塞调用。如果您的应用程序有更多异步工作要做,您可以获得更好的可扩展性。
如果您查看一个单个 请求,并且每个操作一次完成一个,则异步版本稍微慢一些。但是,如果您将系统视为一个整体 - 尤其是 在负载下 - 异步版本的扩展性更好。异步处理程序经常被忽视的另一个方面是,异步版本对突发负载的响应速度比线程池本身更快。
此外,异步代码使得执行并发请求变得容易,这也可以使单个请求更快:
public async Task<SomeViewModel> Get(int id)
{
var someDataTask = _service.GetData(id);
var someOtherDataTask = _service.GetMoreData(id);
await Task.WhenAll(someDataTask, someOtherDataTask);
return new SomeViewModel
{
Data = await someDataTask,
OtherData = await someOtherDataTask,
}
}
关于c# - .Net WebApi 中的多个等待异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22814134/