单向

单项示例演示了具有单向服务操作的服务协定。 客户端不会像双向服务操作那样等待服务操作完成。 此示例基于入门并使用 wsHttpBinding 绑定。 此示例中的服务是一个自承载控制台应用程序,可用于观察接收和处理请求的服务。 客户端也是控制台应用程序。

注释

本示例的设置过程和生成说明位于本主题末尾。

若要创建单向服务协定,请定义您的服务协定,将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);
}

为了演示客户端不会等待服务作完成,此示例中的服务代码实现 5 秒延迟,如以下示例代码所示:

// This service class implements the service contract.
// This code writes output to the console window.
 [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
    InstanceContextMode = InstanceContextMode.PerCall)]
public class CalculatorService : IOneWayCalculator
{
    public void Add(double n1, double n2)
    {
        Console.WriteLine("Received Add({0},{1}) - sleeping", n1, n2);
        System.Threading.Thread.Sleep(1000 * 5);
        double result = n1 + n2;
        Console.WriteLine("Processing Add({0},{1}) - result: {2}", n1, n2, result);
    }
    ...
}

当客户端调用服务时,调用将返回,而无需等待服务作完成。

运行示例时,客户端和服务活动会显示在服务和客户端控制台窗口中。 可以看到服务从客户端接收消息。 在每个控制台窗口中按 Enter 关闭服务和客户端。

客户端先于服务完成,表明客户端不会等待单向服务操作完成。 客户端输出如下所示:

Add(100,15.99)
Subtract(145,76.54)
Multiply(9,81.25)
Divide(22,7)

Press <ENTER> to terminate client.

将显示以下服务输出:

The service is ready.
Press <ENTER> to terminate service.

Received Add(100,15.99) - sleeping
Received Subtract(145,76.54) - sleeping
Received Multiply(9,81.25) - sleeping
Received Divide(22,7) - sleeping
Processing Add(100,15.99) - result: 115.99
Processing Subtract(145,76.54) - result: 68.46
Processing Multiply(9,81.25) - result: 731.25
Processing Divide(22,7) - result: 3.14285714285714

注释

根据定义,HTTP 是请求/响应协议;发出请求时,将返回响应。 即使是通过 HTTP 公开的单向服务操作也是如此。 调用作时,服务在执行服务作之前返回 HTTP 状态代码 202。 此状态代码表示已接受请求进行处理,但尚未完成处理。 调用操作的客户端在从服务收到 202 响应之前处于阻止状态。 当使用绑定(配置为使用会话)发送多个单向消息时,这可能会产生某些意外行为。 wsHttpBinding此示例中使用的绑定配置为默认使用会话来建立安全上下文。 默认情况下,保证会话中的消息按发送顺序到达。 因此,发送会话中的第二条消息时,在处理第一条消息之前不会处理该消息。 结果是客户端在完成上一条消息处理之前不会收到消息的 202 响应。 因此,客户端似乎是阻止了每个后续的操作调用。 为避免此行为,此示例将运行时配置为并发将消息调度到不同的实例进行处理。 示例集将InstanceContextMode设置为PerCall,以便每条消息都可以由不同的实例处理。 ConcurrencyMode 设置为 Multiple 允许多个线程一次调度消息。

设置、生成和运行示例

  1. 确保已为 Windows Communication Foundation 示例 执行One-Time 安装过程。

  2. 若要生成解决方案的 C# 或 Visual Basic .NET 版本,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。

  3. 若要在单台计算机或跨计算机配置中运行示例,请按照 运行 Windows Communication Foundation 示例中的说明进行操作。

注释

在运行客户端之前运行服务,并在关闭服务之前关闭客户端。 当客户端无法完全关闭安全会话时,这可以避免客户端异常,因为服务已消失。