【发布时间】:2016-02-26 16:54:17
【问题描述】:
我认为自己在 C# 方面相当出色,但在理解以下代码时遇到了麻烦:
using (var memoryStream = new MemoryStream())
{
var responseStream = httpContext.Response.Body;
httpContext.Response.Body = memoryStream;
await this.next(httpContext);
using (var compressedStream = new GZipStream(responseStream, CompressionLevel.Optimal))
{
httpContext.Response.Headers.Add("Content-Encoding", new [] { "gzip" });
memoryStream.Seek(0, SeekOrigin.Begin);
await memoryStream.CopyToAsync(compressedStream);
}
}
此代码是从压缩 HTTP 响应的 ASP.Net Core 中间件中提取的,并且“令人惊讶”,它可以工作......或者看起来是这样(我用 Fiddler 对其进行了测试)。
先说说我的理解:
- 代码以在
responseStream中引用httpContext.Response.Body开头。 - 然后它将
httpContext.Response.Body引用替换为新初始化的memoryStream。 - 如果我理解 C# 引用的工作原理,我说我们仍然可以引用原始的
httpContext.Response.Body数据和responseStream,而httpContext.Response.Body的新数据是空的。 - 接下来,我们将调用管道中的下一个中间件。
- 因为
this.next()是可等待的,所以我们的代码执行将“停止”,直到所有中间件返回。 - 当我们的代码执行“恢复”时,它会初始化一个
GZipStream,添加一个响应头,并“寻找”到memoryStream的开头。 - 最后,它将内容或
memoryStream复制到compressedStream,然后将其写入responseStream。
那么,memoryStream、compressedStream 和 responseStream 之间的关系是什么?我们创建了compressedStream 来写入responseStream,然后最终写入httpContext.Response.Body,但是从responseStream 到httpContext.Response.Body 的引用不再存在了吗?
【问题讨论】:
标签: c# asp.net-core gzipstream