C# 使用HttpWebRequest传输大文件时出现内存不足异常

C# 使用HttpWebRequest传输大文件时出现内存不足异常,c#,streaming,out-of-memory,C#,Streaming,Out Of Memory,当使用Http.Put处理大文件时,我遇到内存不足异常。我使用的是一个异步模型,如代码所示。我正在尝试向Windows 2008 R2服务器发送8K数据块。当我尝试写入超过5368864字节的数据块时,异常始终发生。以下代码段中的requestStream.Write方法发生异常 寻找原因为什么 注意:较小的文件可以放入。如果我写入本地文件流,逻辑也可以工作。在Win 7 Ultimate客户端计算机上运行VS 2010、.Net 4.0 HttpWebRequest request =

当使用Http.Put处理大文件时,我遇到内存不足异常。我使用的是一个异步模型,如代码所示。我正在尝试向Windows 2008 R2服务器发送8K数据块。当我尝试写入超过5368864字节的数据块时,异常始终发生。以下代码段中的requestStream.Write方法发生异常

寻找原因为什么

注意:较小的文件可以放入。如果我写入本地文件流,逻辑也可以工作。在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();
        }
    }
HttpWebRequest request=(HttpWebRequest)WebRequest.Create(“Http://website/FileServer/filename");
request.Method=WebRequestMethods.Http.Put;
request.SendChunked=true;
request.AllowWriteStreamBuffering=true;
...
BeginGetRequestStream(新的AsyncCallback(EndGetStreamCallback),state);
...
int chunk=8192;//其他值给出相同的结果
....
私有静态void EndGetStreamCallback(IAsyncResult ar){
长限=0;
长文件长度;
HttpState=(HttpState)ar.AsyncState;
Stream requestStream=null;
//结束异步调用以获取请求流。
试一试{
requestStream=state.Request.EndGetRequestStream(ar);
//将文件内容复制到请求流。
FileStream stream=新FileStream(state.FileName、FileMode.Open、FileAccess.Read、FileShare.None、chunk、FileOptions.SequentialScan);
BinaryReader=新的BinaryReader(流);
fileLength=stream.Length;
//将位置设置为流的开头。
binReader.BaseStream.Position=0;
字节[]文件内容=新字节[块];
//从缓冲区读取文件
while(限制<文件长度)
{
fileContents=binReader.ReadBytes(块);
//接下来的两行尝试写入网络和服务器
Write(fileContents,0,chunk);//导致5368864字节后内存不足
requestStream.Flush();//无论是否使用Flush,我都会得到相同的结果
限制+=块;
}
//重要提示:在发送请求之前关闭请求流。
stream.Close();
requestStream.Close();
}
}
你显然有。当
AllowWriteStreamBuffering
true
时,它会缓冲写入请求的所有数据!因此,“解决方案”是将该属性设置为
false

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


POST也会发生同样的情况吗?您的代码是否确实发送了任何数据?您可能需要研究.NET 4新的
CopyTo()
stream方法,其中还提到:“将AllowWriteStreamBuffering设置为true可能会在上载大型数据集时导致性能问题,因为数据缓冲区可能会使用所有可用内存。”是,我们尝试了这一点,但仍然面临着将其设置为true或false的挑战。我希望真正的解决方案不是使用PUT或POST进行更新,而是使用更低级的技术,如WCF或POS(普通的Ole套接字lol)。@pearcewg:如果你找到了一种可靠的方法让它工作,那么就给你的问题(或你自己的答案!)添加一个更新——我也很好奇,以后有参考资料就好了;-)我们最终放弃了这个,取而代之的是通过WCF上传,效果非常好!我建议您也采用同样的解决方案。@pearcewg:很酷,很高兴知道。谢谢你上的是什么课?