首页 > 解决方案 > 使用 HttpClient 上传大负载而无需缓冲

问题描述

我正在使用 HttpClient 发送包含大型多部分有效负载的 POST 请求。事实证明 HttpClient 正在缓冲整个请求,并且通过尝试发送大文件来重新创建内存不足错误非常容易。HttpClient 为构建多部分有效负载提供了一个很好的框架,但是否可以阻止它缓冲请求?

我正在使用 .net 4.7.2

编辑:

我什至尝试过 PushStreamContent:

byte[] binBuffer = new byte[4096];

int iRead = 0;
PushStreamContent partAttachment = new PushStreamContent((stream, content, context) =>
{
    using (Stream strData = File.Open(@"c:\test\big.csv", FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        while ((iRead = strData.Read(binBuffer, 0, binBuffer.Length)) > 0)
        {
            stream.Write(binBuffer, 0, iRead);
        };
    }
    stream.Close();
});

我在流上遇到 OOM 异常。一旦我打了大约 2 个演出就写。

标签: .nethttpclientdotnet-httpclient

解决方案


PushStreamContent 将允许您发送字节流而无需缓冲。

var httpClient = new HttpClient();

var request = new HttpRequestMessage() {
   RequestUri = ... ,
   Method = HttpMethod.POST,
   Content = new PushStreamContent(async (stream, httpContent, transportContext) =>
       { 
          // write to the stream from where ever you are getting the bytes from
          stream.Close();
       })
};

await httpClient.SendAsync(request);

您可以从这里https://github.com/aspnet/AspNetWebStack/blob/master/src/System.Net.Http.Formatting/PushStreamContent.cs#L113看到所有 PushStreamContent 所做的就是它通过 HttpClientHandler 接收网络流SerializeToStream 方法并允许您直接写入它。

我有一个模糊的回忆,早期版本的 .NET 4 存在实际上阻止使用分块传输编码的问题。我记得它是固定的,但我不是 100% 确定它。如果分块编码不起作用,则问题出在管道的 HttpClientHandler 端,而不是在 HttpClient 或 PushStreamContent 中。


推荐阅读