简体   繁体   English

不在.NET Core中处置流

[英]Not disposing stream in .NET Core

Consider ASP.NET Core's ResponseBufferingMiddleware: 考虑一下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;
        }
    }
}

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

Why is this not a memory leak? 为什么这不是内存泄漏? They create a new BufferingWriteStream ( https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs ), but never dispose of it. 他们创建了一个新的BufferingWriteStream( https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs ),但从未对其进行处理。 Does the HTTP Pipeline automatically dispose of streams after a finished request or something? 请求完成后,HTTP管道会自动处理流吗?

This stream is just a wrapper around other stream you pass in its constructor ( originalResponseBody in this case). 此流只是您在其构造函数中传递的其他流的包装(在本例中为originalResponseBody )。 As such - there is no need to dispose it - by itself it does not contain any unmanaged resources it can clear\\release, nor does it contain any other disposable components it should dispose, so there is no reason for it to implement IDisposable , but it inherits from class that already implements it. 这样-不需要处理它-它本身不包含它可以清除\\释放的任何非托管资源,也不包含它应处理的任何其他一次性组件,因此没有理由实现IDisposable ,但是它从已经实现它的类继承。 It just proxies all Stream methods (like Read and so on) to the wrapped stream with some additional logic (buffering). 它只是将所有Stream方法(例如Read等)代理给包装的流,并带有一些附加逻辑(缓冲)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM