并发示例演示如何使用ServiceBehaviorAttributeConcurrencyMode枚举,该枚举控制服务实例是按顺序还是并发处理消息。 此示例基于名为Getting Started的指南,并实现ICalculator
服务协定。 此示例定义了一个新的协定,ICalculatorConcurrency
,该协定继承自ICalculator
,并提供两个额外的操作来检查服务并发的状态。 通过更改并发设置,可以通过运行客户端来观察行为更改。
在此示例中,客户端是一个控制台应用程序 (.exe),服务是由 Internet 信息服务 (IIS) 承载的。
注释
本示例的设置过程和生成说明位于本主题末尾。
有三种可用的并发模式:
Single
:每个服务实例一次处理一条消息。 这是默认并发模式。Multiple
:每个服务实例并发处理多个消息。 服务实现必须线程安全才能使用此并发模式。Reentrant
:每个服务实例一次处理一个消息,但接受可重入调用。 仅当服务对外调用时才会接受这些调用。重入在 ConcurrencyMode.Reentrant 示例中进行了演示。
并发的使用与实例化模式有关。 在PerCall实例化中,并发性不相关,因为每个消息都由一个新的服务实例处理。 在 Single 实例化过程中,与 Single 或 Multiple 并发有关,具体取决于单个实例是依次还是同时处理消息。 在PerSession的实例化过程中,任何并发模式都可能是相关的。
服务类使用 [ServiceBehavior(ConcurrencyMode=<setting>)]
属性来指定并发行为,如下面的代码示例所示。 通过更换注释掉的行,您可以体验 Single
和 Multiple
并发模式。 请记得在更改并发模式后重新生成服务。
// Single allows a single message to be processed sequentially by each service instance.
//[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]
// Multiple allows concurrent processing of multiple messages by a service instance.
// The service implementation should be thread-safe. This can be used to increase throughput.
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
// Uses Thread.Sleep to vary the execution time of each operation.
public class CalculatorService : ICalculatorConcurrency
{
int operationCount;
public double Add(double n1, double n2)
{
operationCount++;
System.Threading.Thread.Sleep(180);
return n1 + n2;
}
public double Subtract(double n1, double n2)
{
operationCount++;
System.Threading.Thread.Sleep(100);
return n1 - n2;
}
public double Multiply(double n1, double n2)
{
operationCount++;
System.Threading.Thread.Sleep(150);
return n1 * n2;
}
public double Divide(double n1, double n2)
{
operationCount++;
System.Threading.Thread.Sleep(120);
return n1 / n2;
}
public string GetConcurrencyMode()
{
// Return the ConcurrencyMode of the service.
ServiceHost host = (ServiceHost)OperationContext.Current.Host;
ServiceBehaviorAttribute behavior = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
return behavior.ConcurrencyMode.ToString();
}
public int GetOperationCount()
{
// Return the number of operations.
return operationCount;
}
}
默认情况下,此示例使用通过 Multiple 实例化的 Single 并发。 客户端代码已修改为使用异步代理。 这允许客户端对服务进行多次调用,而无需等待每个调用之间的响应。 可以观察服务并发模式的行为差异。
运行示例时,操作请求和响应将显示在客户端控制台窗口中。 将显示服务正在运行的并发模式,调用每个操作,然后显示操作计数。 请注意,当并发模式为 Multiple
时,结果将按与调用方式不同的顺序返回,因为服务并发处理多个消息。 通过将并发模式 Single
更改为,结果按调用顺序返回,因为服务按顺序处理每个消息。 在客户端窗口中按 Enter 关闭客户端。
设置、生成和运行示例
确保已为 Windows Communication Foundation 示例 执行One-Time 安装过程。
如果使用 Svcutil.exe 生成代理客户端,请确保包含该
/async
选项。若要生成解决方案的 C# 或 Visual Basic .NET 版本,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。
若要在单台计算机或跨计算机配置中运行示例,请按照 运行 Windows Communication Foundation 示例中的说明进行操作。