![](/img/trans.png)
[英]AuthorizeAttribute not working with Endpoint Routing in ASP.NET Core 3.1
[英]Stream data from an ASP.NET Core 3.1 endpoint without consuming huge amounts of memory
编辑:我有一个诊断中间件组件,可以将响应提取到跟踪文件中。 那是罪魁祸首。 所以,如果你发现这个是因为你有同样的问题:检查你的中间件!
因此,在调用 Web API 端点时,我以流式异步方式从各种数据源收集大量数据(> 100 MB)。 我想以流的方式将该数据转发给客户端。
为此,我构建了自己的IActionResultExecutor<T>
来概括这一点,因为我们有一些这样的端点。
然而,我注意到整个响应在实际发送到客户端之前被缓存在 memory 中。 不好。 显然,我做错了什么,但我无法理解我做错了什么!
执行器的ExecuteAsync
如下所示:
public async Task ExecuteAsync(ActionContext context, AsyncStreamResult result)
{
var bufferingFeature = context.HttpContext.Features.Get<IHttpResponseBodyFeature>();
if (bufferingFeature != null)
bufferingFeature.DisableBuffering();
context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
context.HttpContext.Response.ContentType = "application/json; charset=utf-8";
var cancellationToken = context.HttpContext.RequestAborted;
await context.HttpContext.Response.StartAsync(cancellationToken);
await context.HttpContext.Response.WriteAsync("[", cancellationToken);
bool seenFirstItem = false;
await foreach (var item in result.Data) {
if (seenFirstItem)
await context.HttpContext.Response.WriteAsync(",", cancellationToken);
await context.HttpContext.Response.BodyWriter.WriteAsync(item.JsonBytes, cancellationToken);
seenFirstItem = true;
}
await context.HttpContext.Response.WriteAsync("]", cancellationToken);
}
我可以看到整个过程如何在 Visual Studio 中以线性方式分配大量 memory。 我还可以看到 curl 没有得到任何数据,直到请求完成。 然后一切都在一个 go 中。 具有讽刺意味的是,curl 报告数据的传输编码是chunked
的。 这是一大块,一些数据流超过 100 MB。 仅仅因为这个原因,我在我的 k8s 集群中买不起强大的 pod,在我看来,这个操作应该生成一堆 Gen 0 对象。 但没有什么是 GC 不应该处理的。 引用的对象应该以千字节计算!
我尝试在一些await context.HttpContext.Response.BodyWriter.FlushAsync(cancellationToken)
中撒上一些东西,但似乎没有任何区别。
我究竟做错了什么?
问题已解决:我在管道中有一些调试日志中间件,它打开了缓冲以跟踪发送给客户端的响应。 哦!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.