2011-06-06 161 views
7

當使用大型文件的Http.Put時,出現「內存不足」異常。我正在使用代碼中顯示的異步模型。我試圖將8K數據塊發送到Windows 2008 R2服務器。當我嘗試寫入超過536,868,864字節的數據塊時,將始終發生異常。下面的代碼片段中的requestStream.Write方法發生異常。當使用HttpWebRequest來流式傳輸大文件時,內存溢出異常

尋找原因爲什麼?

注意:較小的文件是PUT OK。如果我寫入本地FileStream,Logic也可以工作。在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

POST是否也發生同樣的情況?你的代碼是否真的發送了任何數據? – svick 2011-06-06 02:17:59

+0

您可能想要查看.NET 4的新的流CopyTo()方法 – Cameron 2011-06-06 02:55:33

回答

16

你顯然有this documented problem。當AllowWriteStreamBufferingtrue時,它緩存寫入請求的所有數據!因此,「解」是該屬性設置爲false

要解決此問題,將HttpWebRequest.AllowWriteStreamBuffering屬性設置爲false。

+1

它也在[文檔](http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest .allowwritestreambuffering.aspx):「將AllowWriteStreamBuffering設置爲true可能會導致上傳大型數據集時出現性能問題,因爲數據緩衝區可能會使用所有可用內存。」 – svick 2011-06-06 06:57:37

+0

是的,我們嘗試了這種方法,並將其設置爲true或false,這仍然存在挑戰。我期望真正的解決方案是不使用PUT或POST來執行更新,而是使用更低級的技術,如WCF或POS(Plain Ole Sockets哈哈)。 – pearcewg 2011-06-08 22:20:30

+0

@pearcewg:如果你找到一個確實可行的方法來讓你的問題(或你自己的答案!)添加一個更新 - 我也很好奇,在將來參考;-) – Cameron 2011-06-08 22:58:12