HttpWebRequest流写入永不完成
我发布文件HttpWebRequest
,以及页眉和页脚。标题(大约0.5K)和实际的文件似乎写得很好,但对于大文件(大约15MB),页脚(它像29个字节)似乎永远不会写入。HttpWebRequest流写入永不完成
using (Stream requestStream = request.GetRequestStream()) {
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
byte[] buffer = new byte[Math.Min(4096L, fileSize)];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) {
requestStream.Write(buffer, 0, bytesRead);
}
// next line never completes
requestStream.Write(postFooterBytes, 0, postFooterBytes.Length);
// code below is never reached
Console.WriteLine("Why do I never see this message in the console?");
}
有什么想法?
ETA:尝试最后Write()
之前刷新流,上关的机会,它会有所帮助,但没有效果。
再次编辑:新增using()
澄清,我不是一个完整的白痴。另请注意,这是在的另一个using()
块的fileStream
。
解决:在HttpWebRequest
关闭AllowWriteStreamBuffering
。看起来像什么时候开启,无论Write()
调用是否写入最后一个字节,直到清除内部缓冲区才会返回。所以最后的Write()
最终还是在竞争,直到我跑出耐心。
因为我最初试图做的是确定进度,所以关闭缓冲使事情变得更加清晰。
一个常见的问题是忘记关闭请求流。您会看到的其中一个症状是,请求从未制定。写入确实完成的可能性很大,但由于您没有关闭请求流,因此对HttpWebRequest.GetResponse()
的调用似乎没有执行。
尝试以下,看看它是否有差别:
using (var requestStream = myRequest.GetRequestStream())
{
// write to the request stream here
}
// Now try to get the response.
另一个可能的问题是数据的大小。首先,你确定服务器可以处理15 MB的上传吗?其次,如果您在缓慢连接时进行此操作,15 MB可能需要一段时间才能发送。我有什么被认为是1.5兆位/秒的“快速”上游连接。充其量,每秒0.15兆字节。发送15兆字节将花费一分多半的时间。
另一种可能性是请求超时。您想查看HttpWebRequest.Timeout
和ReadWriteTimeout
属性。
上面的代码片段位于'using()'块内部,它不是'HttpWebRequest.GetResponse()',它不会被执行,它是最后写入之下的任何代码 - 例如'Console.WriteLine() 。 – 2011-06-02 21:37:06
@大卫:好的。看到我关于大小的说明。 – 2011-06-02 21:40:15
因此,预期的行为似乎是将所有内容都写得很快,但是在等待“真正”写入的时候会挂起最后一次写入调用。因为这种行为在几百K的变化中是一致的 - 文件数据循环完成,则页脚挂起。 – 2011-06-02 21:50:48
当你建立你的请求时,你的内容长度也应该包含标题,确保它不只是设置为文件长度。 您可能尝试的另一件事是当所有事情都说完之后,在电话号码簿上拨打.Flush()
。 我不确定为Jim提供的关闭HttpClient流的含义,它可能会起作用,它可能会使情况变得更糟。
是否使用System.Net.WebClient
不能为您提供足够的灵活性? Theres一个不错的UploadFile()
方法可以使用。
内容长度已考虑页眉和页脚,但谢谢。我试着在最后一个'Write()'之后添加'Flush()',但它从未到达。 – 2011-06-02 22:00:56
通常在托管代码中,行不会在没有异常或抛出异常的情况下变得“无法访问”。你可以尝试在你的最后一次写入中放置一个断点,看看该行执行后会发生什么?你是否曾经从你的'HttpWebRequest'对象中调用'.GetResponse()'? – Jay 2011-06-02 22:05:44
很明显的一点,但是你确定当你不*使用HttpWebRequest时,脚注是发射的,对吧? (例如从浏览器或wget) – harpo 2011-06-02 21:47:25
@harpo我不知道我理解。这是我排出页脚。 – 2011-06-02 21:51:35
你确定你没有永远循环阅读吗? – Daniel 2011-06-02 22:10:29