使用HttpClient上传大型有效负载而不进行缓冲

时间:2019-09-23 19:28:11

标签: .net httpclient dotnet-httpclient

我正在使用HttpClient发送包含大型mutalipart有效负载的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个演出时写。

2 个答案:

答案 0 :(得分:0)

我相信您必须使用HttpWebRequest类来做到这一点。

类似这样的东西:

HttpWebrequest request = _httpClient.Request(url, contentType);

request.AllowWriteStreamBuffering = false;

using( var stream = await request.GetRequestStreamAsync().ConfigureAwait(false))
{
    await yourPayloadMessage.CopyToAsync(stream);
}

答案 1 :(得分:0)

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所做的只是它通过SerializeToStream方法从HttpClientHandler接收网络流,并允许您直接对其进行写入。

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