如何使 OWIN 自承载 MVC 直接写入输出流

本文关键字:输出流 MVC 何使 OWIN | 更新日期: 2023-09-27 17:54:30

我在 OWIN 自托管应用程序下使用 MVC 操作,该操作将大量字节作为文件提供给客户端。数据在内存中生成并缓存,MVC 操作返回一个StreamContent,其中MemoryStream指向我的缓存byte[]

我希望数据将直接从我的缓存中读取并复制到OutputStream.相反,数据从我的MemoryStream复制到基础结构创建的其他数据。当并行发出大量请求时,我可以看到进程内存增长:

return new HttpResponseMessage(HttpStatusCode.OK)
{
    Content = new StreamContent(new MemoryStream(content), content.Length)
    {
        Headers =
        {
            ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileNameStar = fileName,
                Size = content.Length,
            },
            ContentType = MediaTypeHeaderValue.Parse(mediaType),
            ContentLength = content.Length,
        }
    }
};

如何确保我直接返回缓存的MemoryStream而不被复制占用更多内存?

如何使 OWIN 自承载 MVC 直接写入输出流

要克服这个问题,您可以通过使用 Request.GetOwinEnvironment() 从 OWIN 环境中获取它来直接写入OutputStream。若要获取写入的响应内容,可以使用PushStreamContent并使用构造响应时调用的异步回调写入OutputStream

    var outputStream = ((HttpListenerContext)Request.GetOwinEnvironment()["System.Net.HttpListenerContext"]).Response.OutputStream;
    return new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new PushStreamContent(
            async (stream, httpContent, arg3) =>
            {
                await outputStream.WriteAsync(content, 0, content.Length);
                stream.Close();
            })
        {
            Headers =
            {
                ContentDisposition = new ContentDispositionHeaderValue("attachment")
                {
                    FileNameStar = fileName,
                    Size = content.Length,
                },
                ContentType = MediaTypeHeaderValue.Parse(mediaType),
                ContentLength = content.Length,
            }
        }
    };