提问者:小点点

发送数据时,为什么System.Net.HTTP.StreamContent会将整个流读入内存,而忽略给定的缓冲区大小?


下面的代码将整个给定的stream数据读入内存,然后将其作为web请求发送,而不是以较小的块读取和发送数据。例如,如果流产生2 GB的数据,代码将在开始发送请求之前将所有2 GB的数据读入内存缓冲区。传递给StreamContent的构造函数的50 KB缓冲区大小似乎被忽略了。

using (var httpClient = new HttpClient())
{
  using (var content = new StreamContent(stream, 1024*50)) // 50 KB buffer size ignored?
  {
    using (var request = new HttpRequestMessage(HttpMethod.Post, requestUri))
    {
      request.Content = content;
      await httpClient.SendAsync(request);
    }
  }
}

共1个答案

匿名用户

当给定的不支持查找时,就会发生这种情况。在这种情况下,StreamContent不能使用Stream.Lengty属性检索其大小,而这是构造HTTP请求消息所必需的。

但是,如果您指定应该使用“分块传输编码”,它就起作用了。这样,内容就可以分块发送,而不必预先确定其大小。

因此,这段代码将避免将整个数据加载到内存中,即使它不允许查找:

using (var httpClient = new HttpClient())
{
  using (var content = new StreamContent(stream, 1024*50))
  {
    using (var request = new HttpRequestMessage(HttpMethod.Post, requestUri))
    {
      request.Content = content;

      // Enable the request message to be sent without knowing the final content size
      request.Headers.TransferEncodingChunked = true;
      
      await httpClient.SendAsync(request);
    }
  }
}