C# OData是异步的吗?

C# OData是异步的吗?,c#,asp.net-core,entity-framework-core,odata,C#,Asp.net Core,Entity Framework Core,Odata,我正在开发一个OData端点,用于从数据库返回项目列表 我返回一个IQueryable,让前端通过odata查询选项处理查询/过滤/扩展/分页 考虑以下方法: [ODataRoute] [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)] public IActionResult Get() { return Ok(context.Vendors.AsQueryable()); } 我知道实际上并不需要async,因为

我正在开发一个OData端点,用于从数据库返回项目列表

我返回一个
IQueryable
,让前端通过odata查询选项处理查询/过滤/扩展/分页

考虑以下方法:

[ODataRoute]
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
public IActionResult Get() {
    return Ok(context.Vendors.AsQueryable());
}
我知道实际上并不需要
async
,因为这里没有具体化查询

在这种情况下,查询何时具体化


它是以异步方式完成的吗

您的查询将在序列化过程中实现。当您的方法被访问时,为了以JSON返回响应,serialiser会尝试序列化结果。此时,您的查询实际上会命中数据库并返回结果。
应用程序可能会很慢,因为没有应用任何筛选器,并且您的查询试图从数据库检索所有记录

你问了几个问题,我会尽力回答并澄清几个问题

我明白,实际上并不需要异步

异步从来都不是真正需要的问题是异步是否会使您的应用程序受益。例如,当调用DbContext时,有些网络操作需要时间,如果在此期间不使用async,线程将等待响应,而不是返回到线程池来处理其他请求

所以,是的,它是不需要的,但它可能是有用的

在这种情况下,查询何时具体化

当访问端点时,查询被具体化(在中间件中)

它是以异步方式完成的吗


不,当您传递Queryable时,您只是将执行推迟到稍后,这仍然是同步执行的,您需要使用async/Wait模式来异步执行某项操作

方法只有在异步时才是异步的。当访问端点时,查询被具体化(在中间件中),因此异步确实很重要。对,在我发现的每个ODataRESTAPI示例中,这是调用它的正确方法。然而,我们设立了一个小型测试营,大约有30个并发用户,出现了速度缓慢的报告,cpu和内存使用率达到了顶峰。。。我想知道这些API调用是否是原因,我的理论是资源没有被正确释放,并且不断堆积……这些是不同的问题。async/await仅对线程管理有帮助,这样线程就不会阻塞IO调用。异步/等待对内存/资源/cpu使用没有影响。如果资源没有被释放,那么您需要检查如何注册实现IDisposable的类型,并确保它们没有被保留。例如,DbContext类型应该注册为
InstancePerLifetimeScope
(如果使用扩展名,这是默认值)。但是如果您在测试环境和数据库中分析应用程序以查看实际情况,您将取得更大的进步。是的,我会这样做并发回!至少,我所有的前端调用都包含这样一个筛选器:
?$filter=contains(description,${term}')
。不幸的是,我只需要一个Id和描述就可以过滤掉它们。我们确实创建了一些索引,看起来搜索性能更好。我只是想清除后端不必要的额外开销,以及我对async和iQueryTable的任何误解。通常,在长文本字段(如description)上建立索引不是一个好主意。您可以尝试从客户端强制分页。或者将最大记录数限制为固定数字,例如100。用户需要再次查询才能获得下一个100。在现实世界中,我看不到这样的场景,即用户在不滚动或更改页面的情况下一次查看超过20 30条记录。该场景是一个typeahead,我们还包括$top=10,可能您对服务器的调用太频繁了。通常,在发送查询之前,最好等待几毫秒,然后监听用户是否按了其他键。用户完成键入后,发送一次查询。不是每按一次键。