inq*_*ive 6 .net streaming wcf dispose timeout
我正在使用WCF下载一个非常长的文件.它是net-tcp绑定的自托管服务.在客户端上,我正在读取流并将其写入后台线程中的磁盘.在UI上,有一个取消按钮.我用a取消了读写循环CancellationToken.
问题是,
如果Stream过早(不是EOF)那么处理它需要很长时间.
在服务器(c#):
IO.Stream getFile(string filePath) {
return new IO.FileStream(filePath);
}
Run Code Online (Sandbox Code Playgroud)
在客户端(vb):
using proxy as new ServiceReference1.TestServer
using wcfStrm = proxy.getFile("c:\100MB.dat")
using fileStrm = new FileStream("d:\destination\100MB.dat")
dim buff(256) as new Byte
while true
cancellationToken.ThrowIfCancellationRequested
Dim len = wcfStrm.Read(buff, 0, buff.Length)
if len > 0 then
fileStrm.write(buff, 0, len)
else
exit while
end if
end while
end using
end using ' <-------------- this hangs for 10Mins
end using
Run Code Online (Sandbox Code Playgroud)
当CancellationToken抛出时OperationCancelledException,所有三个使用块都试图处理它们的资源.现在,当第二个使用块尝试处理时MessageBodyStream,它会挂起10分钟.但如果完全读取流,则会快速退出.
我怀疑,它与ReceiveTimeout10分钟有关.所以我改为30秒和中提琴!处置现在需要30秒.
还有一件事.该Dispose操作实际上超时.它吃了我,OperationCancelledException并产生了一种TimeoutException说法The sockket transfer timed out after 00:00:00... bla bla bla
以下是堆栈跟踪
System.TimeoutException: The socket transfer timed out after 00:00:00. You have exceeded the timeout set on your binding. The time allotted to this operation may have been a portion of a longer timeout.
at System.ServiceModel.Channels.SocketConnection.SetReadTimeout(TimeSpan timeout, Boolean synchronous, Boolean closing)
at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
at System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
at System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
at System.ServiceModel.Channels.PreReadConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
at System.ServiceModel.Channels.SingletonConnectionReader.SingletonInputConnectionStream.ReadCore(Byte[] buffer, Int32 offset, Int32 count)
at System.ServiceModel.Channels.SingletonConnectionReader.SingletonInputConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.ServiceModel.Channels.MaxMessageSizeStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.ServiceModel.Channels.SingletonConnectionReader.Close(TimeSpan timeout)
at System.ServiceModel.Channels.SingletonConnectionReader.SingletonInputConnectionStream.Close()
at System.ServiceModel.Channels.DelegatingStream.Close()
at System.Xml.XmlBufferReader.Close()
at System.Xml.XmlBaseReader.Close()
at System.Xml.XmlBinaryReader.Close()
at System.ServiceModel.Dispatcher.StreamFormatter.MessageBodyStream.Close()
at System.IO.Stream.Dispose()
at ...somewhere in my code...
Run Code Online (Sandbox Code Playgroud)
我不相信,如果没有完全阅读它就不能取消流.另一方面,我不能忘记流,并让它走,而不是处置.它必须是一个阻塞等待直到安全释放的呼叫.
有人可以帮帮我吗?
堆栈跟踪显示:
' this is interesting
at System.Xml.XmlBinaryReader.Close() ' VVVVVVVVVVVVV
at System.ServiceModel.Dispatcher.StreamFormatter.MessageBodyStream.Close()
at System.IO.Stream.Dispose()
Run Code Online (Sandbox Code Playgroud)
所以我将使用块更改为try-finally块.我放在wcfStrm.close后面wcfStrm.Dispose.令我惊讶的是,紧密的声明迅速通过,处置时间超时.现在,如果内部处置实际的罪魁祸首是Close为什么明确的关闭没有挂起?然后,即使流被关闭,处置也会被绞死?
| 归档时间: |
|
| 查看次数: |
936 次 |
| 最近记录: |