服务器激活

服务器激活的对象是其生存期由服务器直接控制的对象。服务器应用程序域只有在客户端在对象上进行方法调用时才创建这些对象,而不会在客户端调用 new(在 Visual Basic 中为 New())或 Activator.GetObject 时创建这些对象;这节省了仅为创建实例而进行的一次网络往返过程。客户端请求服务器激活的类型实例时,只在客户端应用程序域中创建一个代理。然而,这也意味着当您使用默认实现时,只允许对服务器激活的类型使用默认构造函数。要发布其实例将使用带参数的特定构造函数创建的类型,可以使用客户端激活或者动态地发布您的特定实例。

服务器激活模式

服务器激活的对象有两种激活模式(或 WellKnownObjectMode 值):Singleton 和 SingleCall。

Singleton 类型任何时候都不会同时具有多个实例。如果存在实例,所有客户端请求都由该实例提供服务。如果不存在实例,服务器将创建一个实例,而所有后继的客户端请求都将由该实例来提供服务。由于 Singleton 类型具有关联的默认生存期,因此,即使任何时候都不会有一个以上的可用实例,客户端也不会总接收到对可远程处理的类的同一实例的引用。

SingleCall 类型对于每个客户端请求始终只有一个实例。下一个方法调用将由另一个服务器实例提供服务,即使上一个实例尚未被系统回收。SingleCall 类型不参与生存期租约系统。

为了创建服务器激活的类型的实例,客户端要么以编程方式(或使用配置文件)配置它们的应用程序并调用 new,要么在对 Activator.GetObject 的调用中传递远程对象的配置。

备注

可能不需要在客户端上注册信道。如果客户端未注册信道,远程处理系统将使用在 Machine.config 文件中指定的默认信道之一自动选择或创建一个信道以发出传出的请求。客户端上的这一自动信道选择并不注册信道来侦听服务器中的任何回调函数,并且不注册任何自定义信道实现(除非该自定义信道已添加到 machine.config 文件中)。在这些情况下,必须在客户端应用程序域中注册要使用的信道类型。

下面的代码示例显示一个对 Activator.GetObject 的调用(假定已经注册一个 TcpChannel 以在端口 8080 上通信)。如果客户端只知道服务器对象实现了某个特定的接口,则必须使用对 Activator.GetObject 的调用,这是因为您必须使用 new (在 Visual Basic 中为 New)创建类的实例。

Dim MyRemoteClass As RemoteObjectClass = _
   CType( _
      Activator.GetObject(GetType(RemoteObjectClass), _
         "tcp://computername:8080/RemoteObjectUri" ), _
      RemoteObjectClass
   ) 
RemoteObjectClass MyRemoteClass = (RemoteObjectClass)Activator.GetObject(
   typeof(RemoteObjectClass),
   "tcp://computername:8080/RemoteObjectUri "
);

请记住,前面的调用不在服务器上创建远程对象。它只向客户端返回对远程对象的本地代理的引用。客户端现在可以继续将 MyRemoteClass 当作对远程对象的直接引用。客户端实际上使用哪个实例在方法调用之间进行通信取决于服务器对象是声明为 Singleton 类型还是 SingleCall 类型。无论服务器对象的发布服务器是否公开该信息,客户端都完全同样地对待它具有的对象引用。

Singleton

在 COM 中,“singleton”意味着只要客户端具有对您的对象的引用,就不会将该对象从内存中删除。但是,在 .NET 远程处理中,Singleton 对象要受到为其指定的生存期租约的约束,因此即使客户端当前持有对该对象的引用,仍可以回收该对象。要创建前一种 Singleton 对象,可以重写 MarshalByRefObjectInitializeLifetimeService 方法以返回空引用(在 Visual Basic 中为 Nothing)。只要宿主应用程序域正在运行,这就可以有效地将对象保留在内存中。有关详细信息,请参见生存期租约。您可以通过在远程处理配置文件中配置初始租约时间来创建后一种类型的 Singleton 对象。

请参见

参考

WellKnownObjectMode 枚举
Marshal

概念

远程对象的激活
客户端激活
生存期租约