我发现我的HTTPWebRequest上传在上传的最后阶段失败了...如 this video @Screenr 所示
我的代码如下
using (var reqStream = req.GetRequestStream())
{
BinaryWriter reqWriter = new BinaryWriter(reqStream);
byte[] buffer = new byte[25600]; // 20KB Buffer
int read = 0, bytesRead = 0;
while ((read = memStream.Read(buffer, 0, buffer.Length)) > 0) {
reqWriter.Write(buffer); // at the very last loop, this line causes the error
bytesRead += read;
Debug.WriteLine("Percent Done: " + ((double)bytesRead / memStream.Length * 100) + "% " + DateTime.Now);
}
我不知道您是否需要更多代码,我只是不想在此处发送垃圾邮件。以下异常(exception)
System.Net.WebException was caught
Message=The request was aborted: The request was canceled.
Source=System
StackTrace:
at System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean aborting)
at System.Net.ConnectStream.System.Net.ICloseEx.CloseEx(CloseExState closeState)
at System.Net.ConnectStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.Stream.Dispose()
at QuickImageUpload.ViewModels.ShellViewModel.UploadImage(String filename, String contentType, Byte[] image) in D:\Projects\QuickImageUpload\QuickImageUpload\ViewModels\ShellViewModel.cs:line 190
InnerException: System.IO.IOException
Message=Cannot close stream until all bytes are written.
Source=System
StackTrace:
at System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean aborting)
InnerException:
注意内部异常“在写入所有字节之前无法关闭流”。但是我还没有关闭此循环中的任何流吗?
最佳答案
好吧,您正在通过将流放在using
语句中来关闭流-但您应该将其关闭,因此这不太可能成为问题。
首先要注意以下几点:
BinaryWriter
。它什么都没买。直接写到流中。 memStream
是MemoryStream
,则可以使用WriteTo
:using (var reqStream = req.GetRequestStream())
{
memStream.WriteTo(reqStream);
}
这意味着您将无法获得诊断信息,但是它确实使代码更简单:)
现在,关于正在发生的事情...我的猜测是,您在对
Write
的调用中遇到了一个异常,但是该异常已被关闭流抛出的异常有效地替换了。我有一个主意,为什么也可能引发异常...
您是否在任何地方设置内容长度?因为您可能正在解决它。看这行:
reqWriter.Write(buffer);
这是在循环的每次迭代中写出整个缓冲区,而忽略了您刚刚读取的数据量。您已经分配了读取到变量
read
中的字节数,但是您再也不会使用该值了。您可以通过将其更改为reqWriter.Write(buffer, 0, read);
...但是我个人不会。我要么只是使用
MemoryStream.WriteTo
,要么直接写到请求流中……就像我之前说的那样,BinaryWriter
实际上并没有为您买任何东西。无论如何,在当前代码中,对于每个请求,无论内容长度如何,都将尝试写入25600字节的倍数。如果请求流注意到并抛出异常,我不会感到惊讶。假设我们有30000字节的数据。我怀疑序列是这样的:
IOException
finally
语句的隐式using
块处理流,将其关闭正是这种情况使库从
Dispose
抛出异常是一个坏主意...但是假设我是对的,这确实带来了一个有趣的问题,即您同时尝试写入过多和过少的数据:)