这是我上周一直在调查的一个问题,但找不到任何解决方案。发现了问同样问题的帖子,但从来没有得到答案,希望这也能帮助其他人。
我有一个WCF
服务,它返回一个内部包含stream
的对象。我使用带有流传输的basicHttpBinding
和Mtom将其发送到客户端。
客户端调用WCF
服务,并在收到响应对象后立即关闭代理。
接下来,客户端读取它从WCF服务获得的流,并将其写入本地磁盘上的文件。所有这些都运行得很好。
我的问题是当客户端想要中止操作并停止从WCF服务下载数据时。如果我在流上调用.close()
,例如:serverReply.DataStream.Close();
,那么它会阻塞并读取整个流,直到它结束,然后再继续。流可能非常大,并且网络并不总是很快。
这对于两种网络资源的使用都是非常不可取的,这基本上浪费在不再使用的数据上。由于basicHttpBinding
只允许两个并发的TCP连接(默认情况下)连接到WCF服务服务器,因此它会阻止其他连接尝试,直到流被读取到它的末尾。
我可以增加并发连接的数量,但这将是一个糟糕的解决方案,因为它会造成麻烦。
例如,仍在下载数据并将其丢弃的20次中止下载。我需要让传输完全停止。
在客户机上,流对象只是一个常规的Stream
类,因此它只有close方法,没有其他方法。
在代理对象上调用.close()
或.abort()
没有任何帮助,使用.dispose()
或任何其他方法销毁它也没有帮助。在服务器端,我处理OperationContext.OperationCompleted
事件,但直到读取来自stream
的数据时才触发该事件。
所以问题是,我如何在不完全读取的情况下关闭/中止流?
发布于 2014-08-12 22:52:04
经过调查,我发现WCF客户端将继续从流中读取,直到closeTimeout终止,然后它将中止连接。您可以减少客户端上的closeTimeout以最大限度地减少问题。
注意:您应该将处理流的代码包装到try/catch块中。stream.Dispose()方法将抛出TimeoutException,这会阻止not throwing exceptions in Dispose method的一个指南。
发布于 2015-02-26 17:19:31
我认为您只是在关闭后接收缓冲区。您应该将maxBufferSize设置为较低的值。
您可能还希望通过包装您的流并覆盖读取来限制服务器上读取的数据量。如果您有一个低带宽的客户端,请使用较小的块,并从read方法返回相应的计数,以匹配您实际读取的数量。这将限制缓冲区的填充速率。
我自己在这个主题上的测试涉及我编写一个NeverEndingStream并总是返回数据。在某个时刻,我在客户机上调用了close,然后几乎立即在服务器上调用了close。这表明缓冲区只是被清空了,因为很明显,直到最后它都无法读取我的流。
如果你仍然遇到问题,那么我建议你在被覆盖的流上跟踪Read方法的时间。如果currentReadtime - lastReadTime >x,那么您可以改为调用Close并抛出异常。这肯定会杀了它。
https://stackoverflow.com/questions/11710081
复制相似问题