Использование HttpClient для загрузки большой полезной нагрузки без буферизации - PullRequest
0 голосов
/ 23 сентября 2019

Я использую HttpClient для отправки запроса POST, содержащего большую полезную нагрузку mutlipart.Оказывается, 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 голосов
/ 28 сентября 2019

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%.Если chunked-кодирование не работает, это проблема в конце конвейера HttpClientHandler, а не в HttpClient или PushStreamContent.

0 голосов
/ 23 сентября 2019

Полагаю, вам придется работать с классом HttpWebRequest, чтобы сделать это.

Примерно так:

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

request.AllowWriteStreamBuffering = false;

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