C# WCF:当使用TransferMode=通过netTcpBinding流传输文件到服务器时,对客户端的响应延迟

C# WCF:当使用TransferMode=通过netTcpBinding流传输文件到服务器时,对客户端的响应延迟,c#,.net,wcf,streaming,wcf-binding,C#,.net,Wcf,Streaming,Wcf Binding,我正在使用WCF Streaming将文件从WCF客户端传输到具有netTcpBinding的服务 一旦客户端使用流实例调用服务,服务将开始通过套接字连接(StreamConnection)从流实例读取数据。但是,如果在服务端读取流的过程中发生异常,客户端无法立即获取异常 我发现延迟时间与绑定的sendTimeout有关。如果我设置了sendTimeout=20秒,客户端将在20秒延迟内获得异常;如果sendTimeout=1秒,客户端将立即获得异常 我做了一些调查。我的理解是,即使在服务上抛出

我正在使用WCF Streaming将文件从WCF客户端传输到具有
netTcpBinding
的服务

一旦客户端使用流实例调用服务,服务将开始通过套接字连接(
StreamConnection
)从流实例读取数据。但是,如果在服务端读取流的过程中发生异常,客户端无法立即获取异常

我发现延迟时间与绑定的
sendTimeout
有关。如果我设置了
sendTimeout=20秒
,客户端将在20秒延迟内获得异常;如果
sendTimeout=1秒
,客户端将立即获得异常

我做了一些调查。我的理解是,即使在服务上抛出异常,它也不会抛出到客户端,直到
StreamConnection.Read()/StreamConnection.Write()
超时。此超时时间段看起来与绑定sendTimeout同步

是否可以保留
sendTimeout
并让客户端立即获得异常

这是服务绑定(为了传输大文件,我更改了maxReceivedMessageSize、sendTimeout和receiveTimeout等的值)


与缓冲模式相比,您看到的行为是由于流模式的语义造成的。当使用缓冲连接时,其下面实际上是一个双工连接,即使使用请求/应答也是如此。挂起的接收始终被发布以接受传入的请求或对任何未完成请求的答复。这就是为什么您可以在一个NetTcp连接上通过一个通道从多个线程发送多个未完成的请求。在流模式下,当发出请求时,呼叫实例拥有频道,直到呼叫完成。请求流被发送,并且只有在它被发送之后,我们才对连接发出接收/读取。这是因为,如果请求消息实际上尚未完全发送,即使响应消息是错误消息,也无法获得对请求消息的答复

根据您的需求,您有几个选项来处理此问题,其中大多数选项只需要更改您的服务代码。在服务端,如果抛出异常,则需要捕获异常,排出传入流,然后重新抛出异常,这将导致返回错误消息。当响应流被完全读取时,客户端已经完成了所有发送,现在正在等待响应。这确实需要发送整个请求流,并且在大型请求提前失败的情况下,这可能是不可取的。如果不希望花费时间/带宽来接收消息的其余部分,则可以在服务端对通道进行故障诊断(使用Abort())。这将导致套接字断开连接,您将在客户端收到一个CommunicationException。这样做的缺点是没有收到关于出错原因的信息,但会非常迅速


另一个需要在客户端和服务器端进行更改的选项是使用两个通道,并使用第二个通道在第一个通道上接收有关请求状态的OOB信息。

有人知道吗?
  <netTcpBinding>
    <binding  name="StreamingNetTCPBinding" transferMode="Streamed" maxConnections="500" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" sendTimeout="00:45:00" receiveTimeout="23:00:00" listenBacklog="20">
      <readerQuotas maxArrayLength="2147483647" maxDepth="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647" />
    </binding>
  </netTcpBinding>