在 C# 不同层级的架构中使用 await 的异步任务
在 C# 不同层级的架构中使用 await 的异步任务
最近我一直在烦恼在哪里应该使用await,哪里不需要。
我有一个Repository类用来从数据库中获取数据,如果使用EntityFramework,则代码如下:
public async Task<Listadmin 更改状态以发布 2023年5月19日
- Async performance can be optimized by limiting the number of threads generated or by batching calls
- In case of CPU-bound processing, Async can also help by allowing multiple tasks to run concurrently and not blocking the main thread of execution
- But it's important to note that using Async excessively or inappropriately can actually hurt performance and increase memory usage
- Therefore, it's important to measure the performance impact of Async and optimize it accordingly
- 在纯库调用中,当异步由线程池启动并且分派线程不同于接收线程,且调用不需要重新进入相同的上下文时,应使用
ConfigureAwait(false)
,这意味着它不会等待重新进入原始上下文,这是一种性能提升 - 就像
await
一样,跨整个链,从入口到结束使用ConfigureAwait(false)
是有意义的。这仅适用于那些在很大程度上依赖线程池的库
- 最好阅读这篇文章,Stephen Cleary - There's no thread
- 一个真正的IO异步调用将使用基于硬件的并发来处理,不会阻止软件线程
- 基于CPU的异步处理,您可以将事物放在后台处理,在当前线程需要响应的情况下,主要是在Ui中,如WPF
- 各种系统, 特别是非 MS 框架,如node js,具有异步处理作为基本原则,并且接收端的数据库服务器集群已调整为接收和处理数百万个调用
- B2C调用,每个请求都应该是轻量级且具有有限的有效负载
编辑1:
就在特定情况下,如这里所列出的,ToListAsync
默认是异步的,因此在这种情况下,您可以跳过异步等待,如多个评论中所列出的那样,但是请注意,在一般情况下这可能不是一个很好的策略,因为收益很小,而错误使用的负面影响可能很大,请查看 Stepehen Cleay 的文章进行审查
我想补充一点。
有一些async
方法在其中没有使用async/await
关键词的必要。 正确检测此类误用非常重要,因为添加async
修饰符的代价不菲。
例如,您的示例中不需要使用async/await
关键词。
public Task> GetAsync() { return context.Set
().ToListAsync(); }
然后:
var data = await GetAsync();
就足够了。 在这种情况下,您返回了Task
,然后您在直接处理对象的位置等待它。>
我建议安装async await helper