会话、实例化和并发Sessions, Instancing, and Concurrency

“会话”是在两个终结点之间发送的所有消息的一种相互关系。A session is a correlation of all messages sent between two endpoints. “实例化”是指对用户定义的服务对象以及与其相关的 InstanceContext 对象的生存期的控制。Instancing refers to controlling the lifetime of user-defined service objects and their related InstanceContext objects. “并发”一词是指对 InstanceContext 中同时执行的线程数量的控制。Concurrency is the term given to the control of the number of threads executing in an InstanceContext at the same time.

本主题描述这些设置、它们的使用方法以及它们之间的各种交互作用。This topic describes these settings, how to use them, and the various interactions between them.

会话Sessions

当服务协定将 ServiceContractAttribute.SessionMode 属性设置为 SessionMode.Required时,该协定表示所有调用(即,支持调用的基础消息交换)都必须是同一个对话的一部分。When a service contract sets the ServiceContractAttribute.SessionMode property to SessionMode.Required, that contract is saying that all calls (that is, the underlying message exchanges that support the calls) must be part of the same conversation. 如果某个协定指定它允许使用会话但不要求使用会话,则客户端可以进行连接,并选择建立会话或不建立会话。If a contract specifies that it allows sessions but does not require one, clients can connect and either establish a session or not. 如果会话结束,然后在同一个基于会话的通道上发送消息,将会引发异常。If the session ends and a message is sent over the same session-based channel an exception is thrown.

WCF 会话具有以下主要概念功能:WCF sessions have the following main conceptual features:

  • 它们由调用应用程序显式启动和终止。They are explicitly initiated and terminated by the calling application.

  • 会话期间传递的消息按照接收消息的顺序进行处理。Messages delivered during a session are processed in the order in which they are received.

  • 会话将一组消息相互关联,从而形成对话。Sessions correlate a group of messages into a conversation. 该关联的含义是抽象的。The meaning of that correlation is an abstraction. 例如,一个基于会话的通道可能会根据共享网络连接来关联消息,而另一个基于会话的通道可能会根据消息正文中的共享标记来关联消息。For instance, one session-based channel may correlate messages based on a shared network connection while another session-based channel may correlate messages based on a shared tag in the message body. 可以从会话派生的功能取决于关联的性质。The features that can be derived from the session depend on the nature of the correlation.

  • 没有与 WCF 会话相关联的常规数据存储区。There is no general data store associated with a WCF session.

如果你熟悉 ASP.NET 应用程序中的 System.Web.SessionState.HttpSessionState 类以及它提供的功能,你可能会注意到该类型的会话和 WCF 会话之间存在以下差异:If you are familiar with the System.Web.SessionState.HttpSessionState class in ASP.NET applications and the functionality it provides, you might notice the following differences between that kind of session and WCF sessions:

  • ASP.NET 会话始终由服务器启动。ASP.NET sessions are always server-initiated.

  • ASP.NET 会话是隐式无序的。ASP.NET sessions are implicitly unordered.

  • ASP.NET 会话提供跨请求的常规数据存储机制。ASP.NET sessions provide a general data storage mechanism across requests.

客户端应用程序和服务应用程序以不同方式与会话交互。Client applications and service applications interact with sessions in different ways. 客户端应用程序启动会话,然后接收并处理在该会话内发送的消息。Client applications initiate sessions and then receive and process the messages sent within the session. 服务应用程序可以将会话用作扩展点,以添加其他行为。Service applications can use sessions as an extensibility point to add additional behavior. 通过直接使用 InstanceContext 或实现一个自定义实例上下文提供程序,可以做到这一点。This is done by working directly with the InstanceContext or implementing a custom instance context provider.

实例化Instancing

实例化行为(使用 ServiceBehaviorAttribute.InstanceContextMode 属性进行设置)控制如何创建 InstanceContext 以响应传入的消息。The instancing behavior (set by using the ServiceBehaviorAttribute.InstanceContextMode property) controls how the InstanceContext is created in response to incoming messages. 默认情况下,每个 InstanceContext 都与一个用户定义服务对象相关联,因此(在默认情况下)设置 InstanceContextMode 属性也可以控制用户定义服务对象的实例化。By default, each InstanceContext is associated with one user-defined service object, so (in the default case) setting the InstanceContextMode property also controls the instancing of user-defined service objects. InstanceContextMode 枚举定义了实例化模式。The InstanceContextMode enumeration defines the instancing modes.

可以使用下列实例化模式:The following instancing modes are available:

  • PerCall:为每个客户端请求创建一个新的 InstanceContext (以及相应的服务对象)。PerCall: A new InstanceContext (and therefore service object) is created for each client request.

  • PerSession:为每个新的客户端会话创建一个新的 InstanceContext (以及相应的服务对象),并在该会话的生存期内对其进行维护(这需要使用支持会话的绑定)。PerSession: A new InstanceContext (and therefore service object) is created for each new client session and maintained for the lifetime of that session (this requires a binding that supports sessions).

  • Single:单个 InstanceContext (以及相应的服务对象)处理应用程序生存期内的所有客户端请求。Single: A single InstanceContext (and therefore service object) handles all client requests for the lifetime of the application.

下面的代码示例演示 InstanceContextMode 的默认值(在服务类上显式设置了 PerSession )。The following code example shows the default InstanceContextMode value, PerSession being explicitly set on a service class.

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]   
public class CalculatorService : ICalculatorInstance   
{   
    ...  
}  

ServiceBehaviorAttribute.InstanceContextMode 属性控制释放 InstanceContext 的频率,而 OperationBehaviorAttribute.ReleaseInstanceModeServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete 属性则控制释放服务对象的时间。And while the ServiceBehaviorAttribute.InstanceContextMode property controls how often the InstanceContext is released, the OperationBehaviorAttribute.ReleaseInstanceMode and ServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete properties control when the service object is released.

已知的单一实例服务Well-Known Singleton Services

有时,单个实例服务对象的变体是有用的:您可以自己创建一个服务对象,然后创建使用该对象的服务主机。One variation on single instance service objects is sometimes useful: you can create a service object yourself and create the service host using that object. 为此,您还必须将 ServiceBehaviorAttribute.InstanceContextMode 属性设置为 Single ,否则在打开该服务主机时将引发异常。To do so, you must also set the ServiceBehaviorAttribute.InstanceContextMode property to Single or an exception is thrown when the service host is opened.

可使用 ServiceHost.ServiceHost(Object, Uri[]) 构造函数创建此类服务。Use the ServiceHost.ServiceHost(Object, Uri[]) constructor to create such a service. 当您希望提供一个特定的对象实例供单一实例服务使用时,可以使用它作为实现自定义 System.ServiceModel.Dispatcher.IInstanceContextInitializer 的替代方法。It provides an alternative to implementing a custom System.ServiceModel.Dispatcher.IInstanceContextInitializer when you wish to provide a specific object instance for use by a singleton service. 当服务实现类型难以构造时(例如,如果它不实现无参数的公共构造函数),可以使用此重载。You can use this overload when your service implementation type is difficult to construct (for example, if it does not implement a parameterless public constructor).

请注意,当向此构造函数提供对象时,一些与 Windows Communication Foundation (WCF)实例化行为相关的功能的工作方式有所不同。Note that when an object is provided to this constructor, some features related to the Windows Communication Foundation (WCF) instancing behavior work differently. 例如,在提供单一实例对象实例时,调用 InstanceContext.ReleaseServiceInstance 没有任何效果。For example, calling InstanceContext.ReleaseServiceInstance has no effect when a singleton object instance is provided. 同样,其他任何实例释放机制也都会被忽略。Similarly, any other instance-release mechanism is ignored. ServiceHost 的行为总是像对于所有操作都将 OperationBehaviorAttribute.ReleaseInstanceMode 属性设置为 ReleaseInstanceMode.None 一样。The ServiceHost always behaves as if the OperationBehaviorAttribute.ReleaseInstanceMode property is set to ReleaseInstanceMode.None for all operations.

共享 InstanceContext 对象Sharing InstanceContext Objects

通过自己执行关联,您还可以控制将哪个有会话通道或调用与哪个 InstanceContext 对象相关联。You can also control which sessionful channel or call is associated with which InstanceContext object by performing that association yourself.

并发Concurrency

并发是对 InstanceContext 中在任一时刻处于活动状态的线程数量的控制。Concurrency is the control of the number of threads active in an InstanceContext at any one time. 此控制是通过将 ServiceBehaviorAttribute.ConcurrencyModeConcurrencyMode 枚举结合使用来实现的。This is controlled by using the ServiceBehaviorAttribute.ConcurrencyMode with the ConcurrencyMode enumeration.

有以下三种可用的并发模式:The following three concurrency modes are available:

  • Single:最多允许每个实例上下文同时拥有一个对该实例上下文中的消息进行处理的线程。Single: Each instance context is allowed to have a maximum of one thread processing messages in the instance context at a time. 其他希望使用同一个实例上下文的线程必须一直阻塞,直到原始线程退出该实例上下文为止。Other threads wishing to use the same instance context must block until the original thread exits the instance context.

  • Multiple:每个服务实例都可以拥有多个同时处理消息的线程。Multiple: Each service instance can have multiple threads processing messages concurrently. 若要使用此并发模式,服务实现必须是线程安全的。The service implementation must be thread-safe to use this concurrency mode.

  • Reentrant:每个服务实例一次只能处理一个消息,但可以接受可重入的操作调用。Reentrant: Each service instance processes one message at a time, but accepts re-entrant operation calls. 服务仅在通过 WCF 客户端对象调用时接受这些调用。The service only accepts these calls when it is calling out through a WCF client object.

备注

理解和开发能够安全地使用多个线程的代码可能比较困难。Understanding and developing code that safely uses more than one thread can be difficult to write successfully. 在使用 MultipleReentrant 值之前,应确保已针对这些模式对服务进行了适当设计。Before using Multiple or Reentrant values, ensure that your service is properly designed for these modes. 有关更多信息,请参见ConcurrencyModeFor more information, see ConcurrencyMode.

并发的使用与实例化模式有关。The use of concurrency is related to the instancing mode. PerCall 实例化中,并发性不相关,因为每个消息都由一个新的 InstanceContext 进行处理,因此,在 InstanceContext中永远不会有多个线程处于活动状态。In PerCall instancing, concurrency is not relevant, because each message is processed by a new InstanceContext and, therefore, never more than one thread is active in the InstanceContext.

下面的代码示例演示如何将 ConcurrencyMode 属性设置为 MultipleThe following code example demonstrates setting the ConcurrencyMode property to Multiple.

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]   
public class CalculatorService : ICalculatorConcurrency   
{   
    ...  
}  

会话与 InstanceContext 设置进行交互Sessions Interact with InstanceContext Settings

会话和 InstanceContext 根据协定中 SessionMode 枚举的值和服务实现上的 ServiceBehaviorAttribute.InstanceContextMode 属性的组合进行交互,该组合控制着通道和特定服务对象之间的联系。Sessions and InstanceContext interact depending upon the combination of the value of the SessionMode enumeration in a contract and the ServiceBehaviorAttribute.InstanceContextMode property on the service implementation, which controls the association between channels and specific service objects.

下表显示了在给定服务的 ServiceContractAttribute.SessionMode 属性值和 ServiceBehaviorAttribute.InstanceContextMode 属性值组合的情况下,支持会话或不支持会话的传入通道的结果。The following table shows the result of an incoming channel either supporting sessions or not supporting sessions given a service's combination of the values of the ServiceContractAttribute.SessionMode property and the ServiceBehaviorAttribute.InstanceContextMode property.

InstanceContextMode 值InstanceContextMode value Required Allowed NotAllowed
PerCallPerCall -会话通道的行为:每个调用的会话和 InstanceContext- Behavior with sessionful channel: A session and InstanceContext for each call.
-无会话通道的行为:将引发异常。- Behavior with sessionless channel: An exception is thrown.
-会话通道的行为:每个调用的会话和 InstanceContext- Behavior with sessionful channel: A session and InstanceContext for each call.
-无会话通道的行为:每个调用的 InstanceContext- Behavior with sessionless channel: An InstanceContext for each call.
-会话通道的行为:将引发异常。- Behavior with sessionful channel: An exception is thrown.
-无会话通道的行为:每个调用的 InstanceContext- Behavior with sessionless channel: An InstanceContext for each call.
PerSessionPerSession -会话通道的行为:每个通道的会话和 InstanceContext- Behavior with sessionful channel: A session and InstanceContext for each channel.
-无会话通道的行为:将引发异常。- Behavior with sessionless channel: An exception is thrown.
-会话通道的行为:每个通道的会话和 InstanceContext- Behavior with sessionful channel: A session and InstanceContext for each channel.
-无会话通道的行为:每个调用的 InstanceContext- Behavior with sessionless channel: An InstanceContext for each call.
-会话通道的行为:将引发异常。- Behavior with sessionful channel: An exception is thrown.
-无会话通道的行为:每个调用的 InstanceContext- Behavior with sessionless channel: An InstanceContext for each call.
SingleSingle -会话通道的行为:所有调用的会话和一 InstanceContext- Behavior with sessionful channel: A session and one InstanceContext for all calls.
-无会话通道的行为:将引发异常。- Behavior with sessionless channel: An exception is thrown.
-会话通道的行为:创建的或用户指定的单一实例的会话和 InstanceContext- Behavior with sessionful channel: A session and InstanceContext for the created or user-specified singleton.
-无会话通道的行为:创建的或用户指定的单一实例的 InstanceContext- Behavior with sessionless channel: An InstanceContext for the created or user-specified singleton.
-会话通道的行为:将引发异常。- Behavior with sessionful channel: An exception is thrown.
-无会话通道的行为:每个创建的单一实例或用户指定的单一实例的 InstanceContext- Behavior with sessionless channel: An InstanceContext for each created singleton or for the user-specified singleton.

请参阅See also