不在.NET Core中部署流

时间:2017-03-23 19:13:43

标签: c# asp.net .net asp.net-core

考虑ASP.NET Core的ResponseBufferingMiddleware:

public class ResponseBufferingMiddleware
{
    private readonly RequestDelegate _next;

    public ResponseBufferingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        var originalResponseBody = httpContext.Response.Body;

        // no-op if buffering is already available.
        if (originalResponseBody.CanSeek)
        {
            await _next(httpContext);
            return;
        }

        var originalBufferingFeature = httpContext.Features.Get<IHttpBufferingFeature>();
        var originalSendFileFeature = httpContext.Features.Get<IHttpSendFileFeature>();
        try
        {
            // Shim the response stream
            var bufferStream = new BufferingWriteStream(originalResponseBody);
            httpContext.Response.Body = bufferStream;
            httpContext.Features.Set<IHttpBufferingFeature>(new HttpBufferingFeature(bufferStream, originalBufferingFeature));
            if (originalSendFileFeature != null)
            {
                httpContext.Features.Set<IHttpSendFileFeature>(new SendFileFeatureWrapper(originalSendFileFeature, bufferStream));
            }

            await _next(httpContext);

            // If we're still buffered, set the content-length header and flush the buffer.
            // Only if the content-length header is not already set, and some content was buffered.
            if (!httpContext.Response.HasStarted && bufferStream.CanSeek && bufferStream.Length > 0)
            {
                if (!httpContext.Response.ContentLength.HasValue)
                {
                    httpContext.Response.ContentLength = bufferStream.Length;
                }
                await bufferStream.FlushAsync();
            }
        }
        finally
        {
            // undo everything
            httpContext.Features.Set(originalBufferingFeature);
            httpContext.Features.Set(originalSendFileFeature);
            httpContext.Response.Body = originalResponseBody;
        }
    }
}

链接到实际文件:https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Buffering/ResponseBufferingMiddleware.cs

为什么这不是内存泄漏?他们创建了一个新的BufferingWriteStream(https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs),但从不处理它。 HTTP Pipeline在完成请求之后会自动处理流吗?

1 个答案:

答案 0 :(得分:3)

此流只是您在其构造函数中传递的其他流的包装器(在本例中为originalResponseBody)。因此 - 没有必要处理它 - 它本身不包含任何可以清除\释放的非托管资源,也不包含它应该处理的任何其他一次性组件,因此没有理由它实现{{1但它继承自已实现它的类。它只是通过一些额外的逻辑(缓冲)将所有IDisposable方法(如Stream等)代理到包装流中。