C# 未设置TransfernCodingChunked时,HttpClient抛出OutOfMemory异常

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

为了支持使用进度报告上传大文件(实际上非常大,高达几GB),我们开始使用带有PushStreamContent的HttpClient,如前所述。它的工作非常简单,我们在两个流之间复制字节,下面是一个代码示例:

    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;