【问题标题】:Can (or should) I use IAsyncEnumerable<T> instead of Task<ActionResult<IEnumerable<T>>> in a Web API Controller我可以(或应该)在 Web API 控制器中使用 IAsyncEnumerable<T> 而不是 Task<ActionResult<IEnumerable<T>>>
【发布时间】:2021-03-05 23:20:13
【问题描述】:

我目前有一个网络 API

  • 在存储库中使用FromSqlRaw(...).ToListAsync() 获取一行数据
  • 通过控制器将此数据作为Ok(data.ToArray()) 作为Task&lt;ActionResult&lt;IEnumerable&lt;MyClass&gt;&gt;&gt; 返回。

现在我想知道是否应该或可以使用 IAsyncEnumerable 作为返回类型。这个想法是在存储库和控制器中使用它。然而,在这个(现在已经破旧)thread 中它声明它不应该被使用。这里建议的解决方案类似于:

FromSqlRaw(...).AsNoTracking().AsAsyncEnumerable()

至于控制器,我希望用ActionResult 包裹响应以明确设置返回码。但是,that 目前似乎不起作用。

我应该只为存储库应用解决方案并将结果作为列表在我的控制器中使用还是保持原样?

【问题讨论】:

  • 我认为答案是 API 的使用者永远不会收到可等待的结果,而只会收到结果。
  • 至于控制器,它永远不会,因为 JSON Parser 正在接收异步流并将其作为单一结果提供(已经有一个线程,但我现在找不到它) .我试图让我的存储库使用System.linqToListAsync() 将控制器使用的异步流返回到List&lt;T&gt;。它有效,但我不知道这是否会破坏 IAsyncEnumerable 的目的,因为它现在必须由控制器等待。

标签: entity-framework-core asp.net-core-webapi iasyncenumerable


【解决方案1】:

IAsyncEnumerable 为您提供了一个用于pull-based asynchronous 数据检索的接口。换句话说,这个 API 表示一个迭代器,其中下一项是异步获取的。

这意味着您分几轮接收数据,每轮都是异步的。

  • IAsyncEnumerable 之前,你可以使用IEnumerable&lt;Task&lt;T&gt;&gt;,它代表一堆返回类型为T 的异步操作。

  • Task&lt;IEnumerable&lt;T&gt;&gt; 表示一个返回类型为IEnumerable&lt;T&gt; 的异步操作。


让我们将这些知识应用到 WebAPI:

  • 从 HTTP 消费者的角度来看,Task&lt;ActionResult&lt;T&gt;&gt;ActionResult&lt;T&gt; 之间没有区别。从用户的角度来看,这是一个实现细节。
  • WebAPI 控制器的操作实现请求-响应模型。这意味着在消费者端发送一个请求并收到一个响应。
  • 如果消费者再次调用相同的操作,则会实例化一个新的控制器并处理该请求。

这意味着如果您的 API 的使用者作为操作结果类型公开,则无法利用 IAsyncEnumerable

【讨论】:

  • 但是响应可以是连续的,比如当你返回PushStreamContent内容时。
  • @AgentFire 是的,但我认为从问题的角度来看它超出了范围。
  • 谢谢。所以我没有理由想要像ActionResult&lt;IAsyncEnumerable&lt;T&gt;&gt; 这样的东西,这可能是它在语法上不可能的原因。但是,如果 IAsyncEnumerable&lt;T&gt; 在控制器中作为 List 使用,我是否仍然可以获得 Task&lt;Enumerable&lt;T&gt;&gt; 的优势(无论这些是什么)?
  • @Beltway 如果满足以下条件,那么是的,这可能是有意义的:1)各个元素将在未来的不同时间可用 2)您不想等待所有在你开始消费已经可用的之前。
  • 至于 1):我使用的是.AsNoTracking(),因为数据的实际情况并不那么重要,如果我理解正确的话,这并不重要。至于 2):在性能和并发性方面,这通常不是有利的选择吗?只要IAsyncEnumerable没有我不知道的缺点,我就会去。
猜你喜欢
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 2019-06-23
  • 2012-08-02
相关资源
最近更新 更多