【发布时间】:2022-02-08 00:43:05
【问题描述】:
我有一个 Web API 应用程序,它具有需要流式传输某些数据的功能。然后我有另一个 Web 应用程序,它基本上就像代理一样。这个其他应用程序做了很多其他的事情,比如处理授权等等。它需要连接到 API 端点并通过可能对每行数据进行一些附加处理来传递流。例如,在一种情况下,它需要将该数据写入 Excel 文件。
不幸的是,我看到很多关于如何创建 IAsyncEnumerable 的教程,但没有任何关于实际连接到公开一个端点的教程。
理想情况下,我想实际包装我的 IAsyncEnumerable 并将其与其他一些东西一起返回。这就是我基本上已经对其他非流式端点所做的事情:
public class NonStreamedResult : BaseResult
{
public SomeMetaData MetaData {get; set; }
// here Data is usually small, so returning it all at once is no big deal
public IEnumerable<SomeData> Data {get; set; }
}
//....controller
public async Task<NonStreamedResult> GetNonStreamedData()
在消费端,我使用HttpClient,等待HttpResponseMessage 并使用ReadAsAsync<T> 将该响应转换为对象。
但是,如果我尝试这样做:
public class StreamedResult : BaseResult
{
public SomeOtherMetaData MetaData {get; set; }
// Here data could be huge, so we don't want to have to hold it all in memory at once
public IAsyncEnumerable<SomeData> Data {get; set; }
}
//....controller
public async Task<StreamedResult> GetStreamedData()
当它尝试反序列化时会出错,因为它不知道将IAsyncEnumerable 转换为哪个具体类。
那么连接到使用IAsyncEnumerable 的端点的正确方法是什么不将整个响应加载到内存中(显然),以便我最终可以从代理返回另一个IAsyncEnumerable应用?
如果我仍然可以把它包裹起来就好了,但如果我必须只与裸体 IAsyncEnumerable 一起工作,这并不是世界末日@
请注意,我使用的是 Microsoft.Bcl.AsyncInterfaces NuGet 包,因为我仍然针对早期版本的 .NET 框架。
【问题讨论】:
-
接收数据时,代码必须知道数据的结束位置。在发送多个对象时,您不能在没有分隔符的情况下继续将数据附加到传输的末尾。比在接收端,您必须能够在分隔符周围拆分数据。此外,您可能不会在每次读取时收到一个对象,因此代码必须能够将异步接收数据片段附加到更大的对象中,直到找到分隔符。
标签: c# asp.net-web-api iasyncenumerable