【问题标题】:Out of Memory Exception When Using HttpWebRequest to Stream Large File使用 HttpWebRequest 流式传输大文件时出现内存不足异常
【发布时间】:2011-06-06 10:54:41
【问题描述】:

使用大文件的 Http.Put 时出现内存不足异常。我正在使用代码中显示的异步模型。我正在尝试将 8K 数据块发送到 Windows 2008 R2 服务器。当我尝试写入超过 536,868,864 字节的数据块时,始终会发生异常。异常发生在下面代码 sn-p 中的 requestStream.Write 方法上。

寻找原因?

注意:较小的文件可以放置。如果我写入本地 FileStream,逻辑也可以工作。在 Win 7 Ultimate 客户端计算机上运行 VS 2010、.Net 4.0。

   HttpWebRequest request = (HttpWebRequest)WebRequest.Create("Http://website/FileServer/filename");
   request.Method = WebRequestMethods.Http.Put;
   request.SendChunked = true;
   request.AllowWriteStreamBuffering = true;
   ...

   request.BeginGetRequestStream( new AsyncCallback(EndGetStreamCallback), state);
   ...

   int chunk = 8192; // other values give same result
   ....

   private static void EndGetStreamCallback(IAsyncResult ar) {
        long limit = 0;
        long fileLength;
        HttpState state = (HttpState)ar.AsyncState;

        Stream requestStream = null;
        // End the asynchronous call to get the request stream.

        try {
            requestStream = state.Request.EndGetRequestStream(ar);
            // Copy the file contents to the request stream.

            FileStream stream = new FileStream(state.FileName, FileMode.Open, FileAccess.Read, FileShare.None, chunk, FileOptions.SequentialScan);

            BinaryReader binReader = new BinaryReader(stream);
            fileLength = stream.Length;

            // Set Position to the beginning of the stream.
            binReader.BaseStream.Position = 0;

            byte[] fileContents = new byte[chunk];

            // Read File from Buffer 
            while (limit < fileLength)
            {
                fileContents = binReader.ReadBytes(chunk);

                // the next 2 lines attempt to write to network and server
                requestStream.Write(fileContents, 0, chunk);   // causes Out of memory after 536,868,864 bytes
                requestStream.Flush();  // I get same result with or without Flush

                limit += chunk;
            }

            // IMPORTANT: Close the request stream before sending the request.
            stream.Close();

            requestStream.Close();
        }
    }

【问题讨论】:

  • POST 也会发生同样的情况吗?您的代码实际上是否发送任何数据?
  • 您可能想查看 .NET 4 的新 CopyTo() 流方法

标签: c# streaming out-of-memory


【解决方案1】:

你显然有this documented problem。当AllowWriteStreamBufferingtrue 时,它会缓冲写入请求的所有数据!所以,“解决方案”是将该属性设置为false

要解决此问题,请将 HttpWebRequest.AllowWriteStreamBuffering 属性设置为 false。

【讨论】:

  • the documentation 中也提到:“将 AllowWriteStreamBuffering 设置为 true 可能会在上传大型数据集时导致性能问题,因为数据缓冲区可能会使用所有可用内存。”
  • 是的,我们尝试了这一点,并继续面临将其设置为真或假的挑战。我希望真正的解决方案是不使用 PUT 或 POST 进行更新,而是使用更底层的技术,如 WCF 或 POS(Plain Ole Sockets lol)。
  • @pearcewg:如果您找到了一种可靠的工作方式,请为您的问题(或您自己的答案!)添加更新——我也很好奇,它会以后有参考就好了 ;-)
  • 我们最终放弃了这个,并将其替换为通过 WCF 上传,效果非常好!我建议您查看相同的解决方案。
  • @pearcewg:很酷,很高兴知道。谢谢!你用的是什么类?
猜你喜欢
  • 2018-01-13
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 2020-08-30
  • 1970-01-01
  • 2018-05-27
相关资源
最近更新 更多