IQueryable 和 IQueryable<T> 是异步的吗?

Posted

技术标签:

【中文标题】IQueryable 和 IQueryable<T> 是异步的吗?【英文标题】:Are IQueryable and IQueryable<T> async? 【发布时间】:2019-04-24 08:35:23 【问题描述】:

接口IQueryableIQueryable&lt;T&gt; 是异步的吗?

我的意思是,假设以下代码:

void Method()

    var customers = CustomerReposity.ToQueryable(); //The execution of query starts here.

    DoSomething();

    foreach (var customer in customers) // The foreach await to finish
        customer.DoSomething();

我的猜测对吗?如果不是,实现异步行为的正确形式是什么?

也许……

async void Method()

    var customers = CustomerReposity.ToQueryable().ToListAsync(); //The execution of query starts here.

    DoSomething();

    foreach (var customer in await customers) // The foreach await to finish
        customer.DoSomething();

这是个好主意吗?

【问题讨论】:

这个问题好像是:什么时候使用异步方法? @TânNguyễn 不,我知道什么时候使用异步,问题是 IQueryable 接口是否默认是异步的。 IQueryableasync 无关。 ToListAsync 只是使用异步任务将项目转换为列表的扩展方法(需要await)。 除了Tan的回复,IQueryable更像,你需要的时候我给你,或者延迟加载。我什至不会打扰您的第一个代码块async-ing @TânNguyễn 当我调用IQueryable.ToListAsync()时开始执行查询?因为在我使用 foreach 之前查询是并行运行的,所以在 foreach 上等待它是一个好主意吗? DoSomething() 方法可以长时间运行。 【参考方案1】:

不,IQueryableIQueryable&lt;T&gt; 不是异步的,也不需要异步。这两个接口提供了从源中提取一些数据的方法,但由源提供异步支持。如果源将返回内存中的所有数据,那么异步使用它是没有意义的。但是,如果源是从网络“流式传输”的,那么异步枚举它可能是有意义的。

【讨论】:

更准确地说,接口(和接口成员定义)不能是异步的。接口成员的实现可以是,只要其实现的方法满足为async方法的要求(如返回TaskTask&lt;T&gt;)。 更准确地说,只有 方法 可以是异步的。 :-) 好的,我认为我的问题是错误的。我知道IQueryable 推迟执行查询,直到它被转换或在 foreach 中使用。我的问题是,如果检索数据源是一个长时间运行的过程(如数据库连接),如果我在 foreach 中使用IQueryableIQueryable&lt;T&gt;,线程会被阻塞直到我得到结果?我可以在 foreach 中使用它之前异步启动查询执行吗?在 foreach 中使用之前调用 IQueryable.ToAsyncEnumerable()IQueryable.ToListAsync() 是否是启动查询执行的正确方法? await xxx.ToListAsync() 将使您的查询异步执行,即等待此方法将导致您的线程返回线程池并可以运行其他内容,直到查询执行并返回结果到数据库。您的代码foreach (var customer in await customers) 正是这样做的。所以是的,这是正确的做法。 是的,当你调用xxx.ToListAsync()而不等待它时,查询执行开始,你可以做其他事情。是的,DoSomething() 将在查询在后台执行时并行执行。

以上是关于IQueryable 和 IQueryable<T> 是异步的吗?的主要内容,如果未能解决你的问题,请参考以下文章

IQueryable 和 IEnumerable

IQueryable 或 IList

IQueryable和IEnumerable以及AsEnumerable()和ToList()的区别

IEnumerable 和 IQueryable

C# Entity Framework中的IQueryable和IQueryProvider详解

C# Entity Framework中的IQueryable和IQueryProvider详解