将ReadAsStreamAsync返回的流作为API响应传递,并避免大型内存对象。

4

我正在使用两个API来从外部系统下载大型文档。

我使用一些有关要检索的文档的信息调用API 1,然后API 1扮演“中间人”的角色并调用API 2。 API 1获取二进制文档并将其传递给原始调用者。

我想避免创建表示这些文档的大型内存对象,并只通过流作为响应一直传递,我该如何在所描述的设置('中间人'API)中实现?

以下是我目前在API 1中拥有基本示例:

var request = new HttpRequestMessage(HttpMethod.Post, "https://example.com/api/getdocs");
request.Content = parameters;

// 'ResponseHeadersRead' - indicate completion on reading of headers and not entire response...
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

if (response.StatusCode == HttpStatusCode.OK)
{
     var stream = await response.Content.ReadAsStreamAsync();

     return this.Ok(stream);
}
else
{
    // Logging/error handling...
}

这个响应被原始调用者作为流读取,然后传递给一个FileStreamResult,使文档在客户端机器上下载。

我的问题:

  • var stream = await response.Content.ReadAsStreamAsync() 这行代码是否仍会创建代表文档的大型内存对象?
  • 上述流需要被处理还是底层的HttpContent将负责清理流?如果需要处理,我如何在传递流响应给调用者的同时完成它的处理?(这可能吗?)

相关:https://dev59.com/s1oT5IYBdhLWcg3w4CeO基本上,正如您可以从源代码中看到的那样, HttpRequestMessage.Dispose 唯一要做的就是处理其Content流,如果将其传递给Ok,ASP.Net会为您处理。 - Charlieface
@Charlieface 非常棒,正是我想知道的。 - DGibbs
2个回答

1
您传递给Okstream不应该被处理。 Ok将包装流并将其作为响应馈送回客户端,因此如果您处置它,则响应将失败。
从技术上讲,至少根据IDisposable的口头禅,您应该处置response。但是,这样做会导致它也处理流,因此您也不应该处置response
不要担心会导致任何泄漏:HttpResponseMessage除了内容流之外不处理任何内容。请参见下面的源代码:
     protected virtual void Dispose(bool disposing)
     {
         // The reason for this type to implement IDisposable is that it contains instances of types that implement
         // IDisposable (content). 
         if (disposing && !disposed)
         {
             disposed = true;
             if (content != null)
             {
                 content.Dispose();
             }
         }
     }

你应该使用 using 块来处理 request,尽管它只会处理内容,对于你的情况是 parameters

0
  1. FileStreamResult 从输入流中读取字节到缓冲区(默认为4kb),并将它们写入输出流。 因此,不应创建大的内存对象。
  2. FileStreamResult 中的输入流读取过程被包装在 using 语句中。 它将被正确地处理。

谢谢你的回答 - 我知道 FileStreamResult 会在内部自行处理流的释放,但我的问题特别针对在“中间人”API层创建的流。HttpContent 是否会处理自己的资源清理?如果不会,我该如何安全地释放这个流并返回它? - DGibbs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接