问题描述
我一直在尝试使用 System.Net.Http.HttpClient
要发布一个较大的文件(+ 1GB),但它抛出一个 SystemOutOfMemory
异常:
I've been trying to use System.Net.Http.HttpClient
to POST a larger file (+1GB) but it throws a SystemOutOfMemory
exception:
at System.Net.ScatterGatherBuffers.AllocateMemoryChunk(Int32 newSize)
at System.Net.ScatterGatherBuffers..ctor(Int64 totalSize)
at System.Net.ConnectStream.EnableWriteBuffering()
at System.Net.HttpWebRequest.SetRequestSubmitDone(ConnectStream submitStream)
at System.Net.Connection.CompleteStartRequest(Boolean onSubmitThread, HttpWebRequest request, TriState needReConnect)
at System.Net.Connection.SubmitRequest(HttpWebRequest request, Boolean forcedsubmit)
at System.Net.ServicePoint.SubmitRequest(HttpWebRequest request, String connName)
at System.Net.HttpWebRequest.SubmitRequest(ServicePoint servicePoint)
at System.Net.HttpWebRequest.BeginGetRequestStream(AsyncCallback callback, Object state)
at System.Net.Http.HttpClientHandler.StartGettingRequestStream(RequestState state)
at System.Net.Http.HttpClientHandler.PrepareAndStartContentUpload(RequestState state)
显然,发生在的HttpWebRequest
类似的问题,因为这里讨论:的。
Apparently, a similar problem occurs for HttpWebRequest
as discussed here: http://support.microsoft.com/kb/908573.
有什么办法来设置 AllowWriteStreamBuffering
底层的Web请求到假
?我找不到任何。
Is there any way to set AllowWriteStreamBuffering
of the underlying web request to false
? I can't find any.
干杯,
推荐答案
只是为了拯救别人感兴趣的时候,我回答我自己的问题。
Just to save time of others interested, I'm answering my own question.
在进行一些测试例外似乎是下降到同样的问题与的HttpWebRequest
中的问题进行讨论。我用Microsoft.AspNet.WebApi版本4.0.20710.0。
After a few tests the exception seems to be down to the same issue with HttpWebRequest
as discussed in the question. I use Microsoft.AspNet.WebApi version 4.0.20710.0.
下面是两个等价件code;前者失败的大文件,而后者能正常工作。
Below are two equivalent pieces of code; the former fails on large files, whereas the latter works fine.
顺便说一句,尽管问题的整体利益的HttpClient
变得非常明显: - )
BTW, despite the issue overall benefits of the HttpClient
become really apparent :-)
var clientRef = new System.Net.Http.HttpClient(
new HttpClientHandler()
{
Credentials = new System.Net.NetworkCredential(MyUsername, MyPassword)
});
clientRef.BaseAddress = new Uri(serverAddress);
clientRef.DefaultRequestHeaders.ExpectContinue = false;
clientRef.PostAsync(
MyFavoriteURL,
new System.Net.Http.StreamContent(inputStream)).ContinueWith(
requestTask =>
{
HttpResponseMessage response = requestTask.Result;
response.EnsureSuccessStatusCode();
}, TaskContinuationOptions.LongRunning).Wait();
使用的HttpWebRequest
using HttpWebRequest
// Preauthenticate
var req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(MyFavoriteURL);
req.Credentials = new System.Net.NetworkCredential(MyUsername, MyPassword);
req.Method = "POST";
req.PreAuthenticate = true;
req.Timeout = 10000;
using (var resp = (System.Net.HttpWebResponse)req.GetResponse())
{
if (resp.StatusCode != System.Net.HttpStatusCode.Accepted && resp.StatusCode != System.Net.HttpStatusCode.OK)
{
throw new Exception("Authentication error");
}
}
// Upload
req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(MyFavoriteURL);
req.Credentials = new System.Net.NetworkCredential(MyUsername, MyPassword);
req.Method = "POST";
req.PreAuthenticate = true;
req.Timeout = 1200000;
req.ContentLength = inputStream.Length;
req.ContentType = "application/binary";
req.Headers.Add("ExpectContinue", "false");
req.AllowWriteStreamBuffering = false;
req.Headers.ExpectContinue = false;
using (var reqStream = req.GetRequestStream())
{
inputStream.CopyTo(reqStream);
}
using (var resp = (System.Net.HttpWebResponse)req.GetResponse())
{
if (resp.StatusCode != System.Net.HttpStatusCode.Accepted && resp.StatusCode != System.Net.HttpStatusCode.OK)
{
throw new Exception("Error uploading document");
}
}
这篇关于难道System.Net.Http.HttpClient从HttpWebRequest.AllowWriteStreamBuffering受苦?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!