Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何正确地异步返回对象集合?_C#_.net_Async Await_System.reactive_Entity Framework Core - Fatal编程技术网

C# 如何正确地异步返回对象集合?

C# 如何正确地异步返回对象集合?,c#,.net,async-await,system.reactive,entity-framework-core,C#,.net,Async Await,System.reactive,Entity Framework Core,我需要在我的核心接口中定义返回列表的方法。我的项目在很大程度上依赖于async/await的使用,因此我需要将我的核心引用/接口定义为尽可能异步的。我的数据访问层也使用EF7。我目前在任何地方都使用IAsyncEnumerable 我目前正在决定是继续使用IAsyncEnumerable还是恢复使用TaskiSyncEnumerable在这一点上似乎很有希望。EF7也是。问题是,我不知道也不知道如何使用它。网上几乎没有任何东西告诉任何人如何使用Ix.Net。有一个ToAsyncEnumerabl

我需要在我的核心接口中定义返回列表的方法。我的项目在很大程度上依赖于async/await的使用,因此我需要将我的核心引用/接口定义为尽可能异步的。我的数据访问层也使用EF7。我目前在任何地方都使用
IAsyncEnumerable


我目前正在决定是继续使用
IAsyncEnumerable
还是恢复使用
Task
<代码>iSyncEnumerable在这一点上似乎很有希望。EF7也是。问题是,我不知道也不知道如何使用它。网上几乎没有任何东西告诉任何人如何使用Ix.Net。有一个
ToAsyncEnumerable
扩展,我可以在
IEnumerable
对象上使用它,但它不能异步执行任何操作(或者执行它??)。另一个缺点是给出以下签名:

IAsyncEnumerable GetPersons();
因为这不是一个返回任务的函数,所以我不能在函数块内使用async/await

另一方面,我的直觉告诉我应该坚持使用
Task
。这当然也有它的问题。EF没有返回此类型的扩展方法。它有一个
ToArrayAsync
ToListSync
扩展方法,但这当然需要在方法内部调用wait,因为
Task
不是协变的。这可能是一个问题,因为这会创建一个额外的操作,如果我只返回
Task
对象,就可以避免这个操作


我的问题是:我应该继续使用
iasynceneumerable
(首选)还是将所有内容都更改回
任务
(非首选)?我也愿意接受其他建议。

您应该只使用
任务
返回类型。原因很简单,您不想为每个要读取的对象对数据库懒洋洋地运行一个新查询,所以只需让EF立即查询这些对象,然后将该集合传递下去


当然,您可以将异步列表变成一个异步可枚举列表,但是为什么要麻烦呢。一旦您将数据存储在内存中,就没有理由人为地延迟对它的访问。

我会选择
IAsyncEnumerable
。它允许您保持操作的异步性和惰性

如果没有它,您需要返回
Task
,这意味着您正在将所有结果加载到内存中。在许多情况下,这意味着查询和保存的内存超过了需要的数量


典型的情况是用户调用
Any
on的查询。如果是
Task
它将首先将所有结果加载到内存中,如果是
IAsyncEnumerable
加载一个结果就足够了


同样相关的是,使用
Task
时,您需要同时将整个结果集保存在内存中,而使用
IAsyncEnumerable
时,您可以一次“流”几个结果


同时,这也是生态系统的发展方向。它是通过反应式扩展添加的,本周刚刚添加了一个,很可能会添加。

您似乎理解每个选项的缺点。剩下的只是意见。我的站在IAsyncenemerable一边。谢谢你。你能证明为什么你认为它是更好的选择吗?因为它是懒惰和异步的。这是未来。我同意它的懒惰,这就是我喜欢它的原因。你有什么可以帮助我学会如何使用它的吗?试错法?这都是新东西。您可以克隆他们的代码,并在其中查看哪些操作可用…谢谢。您建议最好的方法是使用EF返回
任务
,而不使用
等待
?为什么不使用等待?只需执行
wait return someflinqquery.ToListAsync()
,因为它会创建一个不必要的异步操作,尤其是当您不需要等待函数中除.ToListAsync以外的任何内容时。异步操作已在运行,但是的,它会创建另一个异步上下文。但是执行
return await Something()
比只返回原始任务要好,因为这将确保异常被封装在任务中(并且不要立即抛出)。
IAsyncEnumerable
已经有相当长的一段时间了。希望它能在C#8中成功。