我已经苦苦挣扎了几天,要检查在哪里等待和不去哪里。
我有一个Repository类,该类从数据库中获取数据。 使用EntityFramework,代码将如下所示:
public async Task<List<Object>> GetAsync()
{
return await context.Set<Object>().ToListAsync();
}
和消费者:
var data = await GetAsync();
并且在顶层,我也在等待此方法。 我应该只在其中一种方法上使用等待吗? 使用资源并在每次等待时创建新线程是否会降低性能?
我已经检查了评论中列出的问题,但它们不涉及性能问题,只是说您可以做到。我想要最佳实践以及为什么/不这样做的原因。
答案 0 :(得分:1)
我想补充一点。
在某些async
方法中,不需要使用async/await
关键字。检测这种滥用很重要,因为添加async
修饰符是有代价的。
E.G。您的示例中不需要async/await
关键字。
public Task<List<Object>> GetAsync()
{
return context.Set<Object>().ToListAsync();
}
然后:
var data = await GetAsync();
就好了。在这种情况下,您将返回Task<List<Object>>
,然后在直接使用对象的地方等待。
我建议安装async await helper
答案 1 :(得分:0)
让我首先了解您问题的实质,困惑与在完整的呼叫链中在哪里使用异步以及在何处不使用以及如何评估使用对性能的影响有关,因为它可能会导致创建更多线程。如果提要超出了此范围,则在注释中添加详细信息,直到尝试回答它们为止。
让我们一一解决。
在调用链中的哪里使用异步,而在哪里不使用?
有什么好处
在后台之后,在完整链中使用异步的地方
await
在给定的位置不允许进一步的代码处理相同的方法,即使它减轻了线程的负担,所以最好是如果存在多个独立调用,它们使用Task.WhenAll
进行汇总,并且代表任务正在等待,当所有任务完成成功/错误(无论状态如何)时,它都会返回Task.Wait
或Task.Result
之类的方法在异步之间进行了中断,则它将不会保持纯异步调用,并且会阻塞调用线程池线程。如何进一步增强异步功能?
ConfigureAwait(false)
,这意味着它不会等待重新输入原始上下文,可以提高性能await
一样,在整个链条中使用ConfigureAwait(false)
,直到结尾。这仅对在线程池上进行大量答复的库有效是否创建了线程
变化
用例
编辑1:
在这种特定情况下,here和ToListAsync
在默认情况下都是异步的,因此您可以跳过这种情况,如variopus注释中所列,尽管您可以回顾一下Stepehen Cleay的文章,可能不是一个很好的策略,因为收益很小,而且使用不当的负面影响很大。