我有一个web应用程序,它的功能需要流一些数据。然后,我有了另一个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框架的早期版本。
发布于 2022-02-07 16:43:05
--我仍然瞄准.NET框架的早期版本。
不会有什么效果的。Unbuffered IAsyncEnumerable support was added in ASP.NET 6。
如果无法升级,则需要编写自己的流JSON解析器和自己的流JSON序列化程序,它们封装在一个定期刷新的自定义格式化程序中。这是一项非平凡的工作.我的答案的其余部分假设您将迁移到.NET 6。
--如果我还能把它包裹起来,那就太好了,但是如果我只能用裸露的IAsyncEnumerable工作,那就不是世界末日了。
包裹不可能起作用。只需考虑定义多个IAsyncEnumerable<T>属性的情况。在处理IAsyncEnumerable<T> 6中的ASP.NET时,必须将其作为顶级类型返回。元数据可以表示为标题。
要使用,首先要确保设置了HttpClient完成选项,以便在接收到标头时将HTTP操作视为“完成”,然后可以获取响应体流并将其传递给JsonSerializer.DeserializeAsyncEnumerable。从下游API检索每一项之后,您可以执行所需的任何处理,然后将其yield流到客户端。
https://stackoverflow.com/questions/71020230
复制相似问题