Чтобы поддерживать загрузку больших (на самом деле очень больших, до нескольких гигабайт) файлов с отчетом о проделанной работе, мы начали использовать HttpClient с помощью PushStreamContent, как описано here. Он работает просто, мы копируем байты между двумя потоками, вот пример кода:HttpClient выбрасывает исключение OutOfMemory, когда TransferEncodingChunked не установлен
private void PushContent(Stream src, Stream dest, int length)
{
const int bufferLength = 1024*1024*10;
var buffer = new byte[bufferLength];
var pos = 0;
while (pos < length)
{
var bytes = Math.Min(bufferLength, length - pos);
src.Read(buffer, 0, bytes);
dest.Write(buffer, 0, bytes);
pos += bufferLength;
dest.Flush();
Console.WriteLine($"Transferred {pos} bytes");
}
dest.Close();
}
Но в начале этого код поднял OutOfMemory исключения после передачи 320 МБ, даже если потребление памяти процесса не было очень высоким (около 500 МБ). Что устранил эту проблему устанавливает флаг TransferEncodingChunked:
request.Headers.TransferEncodingChunked = true;
Не только мы были в состоянии передавать большие файлы с этим флагом, потребление памяти сократилось на 90%.
Я не нашел документацию, требующую использования TransferEncodingChunked, это был скорее процесс проб и ошибок, но в этом сценарии он имеет решающее значение. Тем не менее я озадачен тем, почему исключение вообще выбрано - потребление памяти не очень велико, что вызывает его?
Ну, если данные большие, лучше отправить их в куски, вы находите это удивительным? – demonplus
Я нахожу удивительное исключение OutOfMemory, поднятое так рано. –