单项示例演示了具有单向服务操作的服务协定。 客户端不会像双向服务操作那样等待服务操作完成。 此示例基于入门并使用 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
允许多个线程一次调度消息。
设置、生成和运行示例
确保已为 Windows Communication Foundation 示例 执行One-Time 安装过程。
若要生成解决方案的 C# 或 Visual Basic .NET 版本,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。
若要在单台计算机或跨计算机配置中运行示例,请按照 运行 Windows Communication Foundation 示例中的说明进行操作。
注释
在运行客户端之前运行服务,并在关闭服务之前关闭客户端。 当客户端无法完全关闭安全会话时,这可以避免客户端异常,因为服务已消失。