OData是否支持异步IQueryable?

4
我正在开发一个OData端点,用于从数据库返回一系列项目。
我返回一个 IQueryable,并让前端处理odata查询选项中的查询/筛选/扩展/分页。
考虑以下方法:
[ODataRoute]
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
public IActionResult Get() {
    return Ok(context.Vendors.AsQueryable());
}

我知道async并不是必需的,因为这里没有将查询实现。

在这种情况下,什么时候实现查询?

它是以异步方式执行的吗?


1
一个方法只有在被标记为async时才是异步的。当访问端点时,查询会在中间件中被实现,因此异步确实很重要。 - Gert Arnold
在每个 OData REST API 的例子中,我发现这是正确的调用方式。然而,我们设置了一个小型测试营地,在大约 30 个并发用户的情况下,有报告说速度变慢,CPU 和内存使用量飙升... 我想知道这些 API 调用是否是原因,我的理论是资源没有被正确释放,导致不断积累... - bruno_cw
1
这些是不同的问题。async/await 只有在线程管理方面有帮助,以便线程不会在 IO 调用上阻塞。Async/Await 对内存/资源/CPU 使用没有影响。如果资源没有被释放,则需要检查如何注册实现 IDisposable 的类型,并确保它们不会停留。例如,DbContext 类型应该注册为 InstancePerLifetimeScope(如果使用扩展名,则为默认值)。 - Igor
1
但是如果您在测试环境和数据库中对应用程序进行分析,以查看实际发生的情况,您将取得更多进展。 - Igor
好的,我会这样做并回复! - bruno_cw
2个回答

2
你提出了几个问题,我会尽力回答并澄清一些问题。

我知道async其实并不是必需的

Async从未真正需要,关键是你的应用程序是否受益于它。例如,当调用DbContext时,会进行一些需要时间的网络操作。如果在此期间不使用async,则线程将等待响应,而不是返回到线程池以处理其他请求。

所以,是的,它不是必需的,但它可能非常有用。

在这种情况下,查询何时被实现?

在访问端点时,查询会在中间件中被实现。

这是异步完成的吗?

不是,当你传递Queryable时,只是将执行推迟到稍后,仍然是同步进行的,你需要使用async/await模式才能实现异步操作。

"最初的回答"

0

您的查询将在序列化期间实现。当访问您的方法以返回JSON响应时,序列化器会尝试对结果进行序列化。此时,您的查询实际上会命中数据库并返回结果。 由于未应用任何过滤器且您的查询尝试从数据库检索所有记录,因此应用程序可能会变慢。


至少,我所有的前端调用都包含像这样的过滤器:?$filter=contains(description, '${term}')。不幸的是,我只有Id和Description可以用来过滤它们。我们创建了一些索引,搜索性能似乎有所提高。我只想从后端清除任何不必要的额外开销,也许还有我对异步和IQueryable的误解。 - bruno_cw
通常在像描述这样的长文本字段上建立索引并不是一个好主意。你可以尝试的一件事是从客户端强制分页,或者将最大记录数限制为固定数量,比如100条。用户需要再次查询以获取下一个100条记录。在现实世界的场景中,我无法想象用户会一次查看超过20到30条记录而不滚动或更改页面。 - Shahzad
场景是一个类型前瞻,我们还在其中包括了 $top=10 - bruno_cw
也许你对服务器的调用太频繁了。通常,在发送查询之前等待几毫秒并监听是否有用户按下其他键是一个好主意。当用户完成输入后,再发送一次查询。不要在每次按键时都发送。 - Shahzad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接