C# 未设置TransfernCodingChunked时,HttpClient抛出OutOfMemory异常
为了支持使用进度报告上传大文件(实际上非常大,高达几GB),我们开始使用带有PushStreamContent的HttpClient,如前所述。它的工作非常简单,我们在两个流之间复制字节,下面是一个代码示例:C# 未设置TransfernCodingChunked时,HttpClient抛出OutOfMemory异常,c#,upload,httpclient,large-files,C#,Upload,Httpclient,Large Files,为了支持使用进度报告上传大文件(实际上非常大,高达几GB),我们开始使用带有PushStreamContent的HttpClient,如前所述。它的工作非常简单,我们在两个流之间复制字节,下面是一个代码示例: private void PushContent(Stream src, Stream dest, int length) { const int bufferLength = 1024*1024*10; var buffer = new b
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();
}
我们不仅能够使用此标志集传输巨大的文件,而且内存消耗减少了90%
我还没有发现任何需要使用TransferncodingChunked的文档,这更像是一个尝试和失败的过程,但在这个场景中似乎至关重要。但我仍然不明白为什么会抛出异常-内存消耗不是很高,是什么原因造成的?
分块传输编码是版本1.1中的一种数据传输机制
超文本传输协议(HTTP)的一种,其中数据以
一系列的“块”。它就地使用传输编码HTTP头
的内容长度标头,该标头是
否则,该协议将需要。因为内容长度标题
如果未使用,则发送方不需要知道
内容,然后再开始向接收器发送响应。
发件人可以在发送之前开始发送动态生成的内容
知道该内容的总大小
每个区块的大小发送到区块本身之前,以便
接收器可以告诉它什么时候已经完成接收数据
大块数据传输以最后一段长度终止
零
如果我们从逻辑上考虑,文件是以小数据块发送的,这意味着当您完成一个数据块时,您将从内存中释放它。最后,您的内存消耗更少,因为您要处理多个小数据块 嗯,如果数据很大,最好是成批发送,你觉得这令人惊讶吗?我发现这么早就出现了令人惊讶的OutOfMemory异常。这很有意义,也解释了内存消耗下降的原因。然而,抛出OutOfMemory异常仍然很奇怪。如果我不使用PushStreamContent并坚持使用由HttpClient完全控制的传统StreamContent,则不会出现例外情况。@VagifAbilov我无法告诉您原因,这需要研究,这是一个不同的问题。您可以检查以下问题:。他们说,推流内容在需要将数据推送到流时使用,而流内容在需要从流中提取时使用。感谢链接,非常有用。
request.Headers.TransferEncodingChunked = true;