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

+0

很明显的一点,但是你确定当你不*使用HttpWebRequest时,脚注是发射的,对吧? (例如从浏览器或wget) – harpo 2011-06-02 21:47:25

+0

@harpo我不知道我理解。这是我排出页脚。 – 2011-06-02 21:51:35

+0

你确定你没有永远循环阅读吗? – Daniel 2011-06-02 22:10:29

解决:在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.TimeoutReadWriteTimeout属性。

+0

上面的代码片段位于'using()'块内部,它不是'HttpWebRequest.GetResponse()',它不会被执行,它是最后写入之下的任何代码 - 例如'Console.WriteLine() 。 – 2011-06-02 21:37:06

+0

@大卫:好的。看到我关于大小的说明。 – 2011-06-02 21:40:15

+0

因此,预期的行为似乎是将所有内容都写得很快,但是在等待“真正”写入的时候会挂起最后一次写入调用。因为这种行为在几百K的变化中是一致的 - 文件数据循环完成,则页脚挂起。 – 2011-06-02 21:50:48

当你建立你的请求时,你的内容长度也应该包含标题,确保它不只是设置为文件长度。 您可能尝试的另一件事是当所有事情都说完之后,在电话号码簿上拨打.Flush()。 我不确定为Jim提供的关闭HttpClient流的含义,它可能会起作用,它可能会使情况变得更糟。

是否使用System.Net.WebClient不能为您提供足够的灵活性? Theres一个不错的UploadFile()方法可以使用。

+0

内容长度已考虑页眉和页脚,但谢谢。我试着在最后一个'Write()'之后添加'Flush()',但它从未到达。 – 2011-06-02 22:00:56

+0

通常在托管代码中,行不会在没有异常或抛出异常的情况下变得“无法访问”。你可以尝试在你的最后一次写入中放置一个断点,看看该行执行后会发生什么?你是否曾经从你的'HttpWebRequest'对象中调用'.GetResponse()'? – Jay 2011-06-02 22:05:44