WCF - 实例管理

WCF用于将一组消息(客户端请求)绑定到服务实例的技术集称为实例管理. WCF支持三种类型的实例激活,本章将对它们进行讨论.

每个呼叫服务

每个呼叫服务是默认的实例激活WCF的模式.为每个呼叫服务配置WCF服务时,将为客户端呼叫或请求正在进行的时间跨度创建CLR对象. CLR代表公共语言运行时,它包括WCF中的服务实例.

在每个呼叫服务中,每个客户端请求实现一个新的专用服务实例,并且与其他客户端请求相比,其内存消耗较少实例激活的类型.

需要将InstanceContextMode属性设置为InstanceContextMode.PerCall,以指示WCF服务充当每个呼叫服务. InstanceContextMode属性属于ServiceBehavior属性.因此,每个呼叫服务可以配置如下 :

[ServiceContract]
interface IMyContract
{...}
[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract
{...}

服务在这里表示为IMyContract.下图显示了每次呼叫服务实例激活的过程.

每个呼叫服务的Wcf实例管理

实施每次呼叫服务

[DataContract]
class Param {....}

[ServiceContract]
interface IMyContract {
   [OperationContract]
   void MyMethod(Param objectIdentifier);
}
class MyPerCallService : IMyContract, IDisposable {
   public void MyMethod(Param objectIdentifier) {
      GetState(objectIdentifier); 
      DoWork();
      SaveState(objectIdentifier);
   }
   
   void GetState(Param objectIdentifier) {....}
   void DoWork() {....}
   void SaveState(Param objectIdentifier) {....}
   public void Dispose() {....}
}

这里,Param是伪类型为上面的例子发明的参数.

每会话服务

在WCF的这种激活模式中,我们可以说是私密或者是机密会话在两个实体之间维护,即客户端和特定服务实例.每个会话服务也称为私有会话服务,它提供了一个新的服务实例,该实例仍然专用于每个客户端请求,并且与该会话感知服务相关的所有其他实例都是自治的.

要启动每会话服务,需要将InstanceContextMode属性设置为PerSession.这里,服务实例在整个会话期间都保留在内存中.

激活模式的可扩展性受到影响,因为配置的服务无法支持除少数之外的任何其他未完成的客户端(或者可能)由于每个专用服务实例都涉及到成本,因此每个会话服务可以配置为 :

[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract
{...}

每个会话服务的过程可以描述如下图所示 :

每个会话服务的Wcf实例管理

以下代码显示为私有会话的使用配置的合同和服务.输出表明客户端确实有一个专用服务实例.

服务代码

[ServiceContract(Session = true)]
interface IMyContract {
   [OperationContract]
   void MyMethod();
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract, IDisposable {
   int m_Counter = 0; MyService() {Console.WriteLine("MyService.MyService()"); }
   
   public void MyMethod() {
      m_Counter++;
      Console.WriteLine("Counter = " + m_Counter);
   }
   public void Dispose() { 
      Console.WriteLine("MyService.Dispose()"); 
   }
}

客户代码

MyContractProxy proxy = new MyContractProxy(); proxy.MyMethod(); proxy.MyMethod(); 
proxy.Close();

输出

MyService.MyService() Counter = 1 Counter = 2 MyService.Dispose()

单例服务

在WCF的这种激活模式下,所有客户端请求都独立于每个其他连接到同一个众所周知的单个实例,无论它们与服务端点的连接如何.单例服务仅在主机关闭时才会被释放.

此服务仅在创建主机时创建一次.如果主机未提供任何单例实例,则服务返回NULL.当每个方法调用中的工作量很少并且后台没有待处理操作时,激活模式处于最佳状态.

InstanceContextMode属性需要设置为InstanceContextMode.Single to启动此Singleton服务.

因此,Singleton服务可以配置为 :

 
 [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single)] 
 class MySingleton:... 
 {...}

Singleton服务的过程如下图所示 :

Wcf Instance Management Singleton Service

以下代码用于初始化和托管单例实例.

服务代码

[ServiceContract]
interface IMyContract {
   [OperationContract]
   void MyMethod( );
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : IMyContract {
   int m_Counter = 0;
   
   public int Counter {
      get {
         return m_Counter;
      }
      set {
         m_Counter = value;
      }
   }
   public void MyMethod( ) {
      m_Counter++;
      Trace.WriteLine("Counter = " + Counter);
   }
}

主机代码

MySingleton singleton = new MySingleton( );
singleton.Counter = 42;
ServiceHost host = new ServiceHost(singleton);
host.Open( );

//Do some blocking calls then
host.Close( );

客户代码

MyContractClient proxy = new MyContractClient( );
proxy.MyMethod( );
proxy.Close( );

输出

Counter = 43