单向服务

服务作的默认行为是请求-回复模式。 在请求-回复模式中,客户端将在等待回复消息,尽管服务操作在代码中被表示为 void 方法。 使用单向操作时,仅传输一条消息。 接收方不会发送回复消息,发送方也不需要发送回复消息。

使用单向设计模式:

当操作是单向的时,没有响应消息可以将错误信息传回客户端。 可以通过使用基础绑定的功能(如可靠会话)或通过设计一个可使用两个单向操作的双工服务协定(一个单向协定从客户端到服务,用于调用服务操作;另一个单向协定在服务和客户端之间,以使服务可以使用客户端实现的回调将错误发回到客户端)来检测错误条件。

若要创建单向服务协定,请定义服务协定,将OperationContractAttribute类应用于每个作,并将属性IsOneWay设置为true,如以下示例代码所示。

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]  
public interface IOneWayCalculator  
{  
    [OperationContract(IsOneWay=true)]  
    void Add(double n1, double n2);  
    [OperationContract(IsOneWay = true)]  
    void Subtract(double n1, double n2);  
    [OperationContract(IsOneWay = true)]  
    void Multiply(double n1, double n2);  
    [OperationContract(IsOneWay = true)]  
    void Divide(double n1, double n2);  
}  

有关完整示例,请参阅 单向 示例。

单向操作的客户端阻止

值得注意的是,虽然一些单向应用程序可以在出站数据写入到网络连接后立即返回,但在几种情况下,绑定或服务的实现可导致 WCF 客户端阻止使用单向操作。 在 WCF 客户端应用程序中,WCF 客户端对象在出站数据写入网络连接之前不会返回。 对于所有消息交换模式(包括单向作)都是如此;这意味着将数据写入传输时出现问题会阻止客户端返回。 根据问题,结果可能是向服务发送消息时出现异常或延迟。

例如,如果传输找不到终结点,System.ServiceModel.EndpointNotFoundException 则会几乎没有延迟地引发异常。 但是,由于某种原因,服务也可能无法读取网络上的数据,这将阻止客户端传输发送操作返回。 在这些情况下,如果超出了客户端传输绑定上的 Binding.SendTimeout 期限,则会引发 System.TimeoutException,但会在超出超时期限后引发。 在向某个服务发送过多消息时,该服务可能会在处理这些消息时卡在某个点,无法继续处理。 在这种情况下,单向客户端也会发生阻止,直到服务可以处理这些消息或直到引发异常。

另一种变化是服务 ServiceBehaviorAttribute.ConcurrencyMode 属性设置为 Single 且绑定使用会话的情况。 在这种情况下,调度程序会对传入消息强制执行排序(会话的需求),这会阻止从网络上读取后续的消息,直到服务处理完该会话的前一个消息为止。 同样,客户端会阻止,但是否发生异常取决于服务能否在客户端上的超时设置之前处理等待数据。

可以通过在客户端对象和客户端传输的发送作之间插入缓冲区来缓解此问题。 例如,使用异步调用或使用内存中消息队列可以使客户端对象快速返回。 这两种方法可能会增加功能,但线程池和消息队列的大小仍会强制实施限制。

相反,建议检查服务以及客户端上的各种控件,然后测试应用程序方案,以确定任一端的最佳配置。 例如,如果会话的使用阻止了服务上的消息处理,则可以将ServiceBehaviorAttribute.InstanceContextMode属性PerCall设置为使每个消息都可以由不同的服务实例处理,并设置为ConcurrencyModeMultiple允许多个线程一次调度消息。 另一种方法是增加服务和客户端绑定的读取配额。

另请参阅