如何从WCF服务中止流而不将其读取到末尾?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (21)

这是我上周正在调查的问题,无法找到任何解决方案。找到相同的帖子,但从来没有得到答案,希望这也会帮助其他人。

我有一个WCF服务返回一个包含stream它的对象。我使用basicHttpBinding流式传输和Mtom将其发送给客户端。

客户端WCF在收到响应对象后立即调用服务并关闭代理。

接下来,客户端读取它从WCF服务获取的流并将其写入本地磁盘上的文件。所有这些工作正常。

我的问题是当客户端想要中止操作并停止从WCF服务下载数据时。如果我调用.close()流,例如:serverReply.DataStream.Close();然后阻塞并从WCF服务读取整个流直到它结束,然后继续。流可能非常大,网络并不总是很快。

这对于网络资源使用来说是非常不希望的,这基本上浪费在不再有用的数据上。由于basicHttpBinding只允许两个并发的TCP连接(默认情况下)到WCF服务服务器,它会阻止其他连接尝试,直到流被读取直到其结束。

我可以增加并发连接的数量,但这将是一个不好的解决方案,因为它会引发麻烦。

例如,20次中止下载,仍在下载数据将其丢弃。我需要完全停止转移。

在客户端,流对象只是一个普通的Stream类,所以它只有close方法,没有别的。

调用.close().abort()代理对象不会有帮助,也不会破坏它使用.dispose()或任何其他方法。在服务器端,我处理OperationContext.OperationCompleted事件,但直到stream读取的数据直到结束才被触发。

所以问题是,如何在没有完全阅读的情况下关闭/中止流?

提问于
用户回答回答于

你玩过binding.MaxBufferSize吗? 你有没有尝试玩你的app.config文件设置,例如:

<bindings>
  <wsHttpBinding>
    <binding name="default" maxReceivedMessageSize="2147483647"  maxBufferPoolSize="2147483647" 
             closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" >
      <readerQuotas  maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384"
                     maxDepth="64" maxStringContentLength="2147483647" />
    </binding>

  </wsHttpBinding>
</bindings>

我会尽量减少超时和缓冲区长度,并尝试中止或关闭,看看会发生什么。

用户回答回答于

经过调查,我发现WCF客户端将继续从流中读取直到closeTimeout ellapsed,然后它会中止连接。可能会减少客户端的closeTimeout以最小化问题。

注意:应该将放置流的代码封装到try / catch块中。stream.Dispose()方法会抛出TimeoutException,这会在Dispose方法中制止不抛出​​异常的指导原则。

扫码关注云+社区