使用HttpWebRequest流式传输大型文件时出现内存异常

时间:2011-06-06 01:17:06

标签: c# streaming out-of-memory

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

寻找原因?

注意:较小的文件是PUT OK。如果我写入本地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();
        }
    }

1 个答案:

答案 0 :(得分:16)

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

  

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