【IT168技术文档】
远程对象的激活模式分服务端激活和客户端激活两种,(也就是对象分服务端激活对象或者说是知名对象和客户端激活对象两种)先看看msdn怎么描述服务端激活的:
服务器激活的对象是其生存期由服务器直接控制的对象。服务器应用程序域只有在客户端在对象上进行方法调用时才创建这些对象,而不会在客户端调用 new 或 Activator.GetObject 时创建这些对象;这节省了仅为创建实例而进行的一次网络往返过程。客户端请求服务器激活的类型实例时,只在客户端应用程序域中创建一个代理。然而,这也意味着当您使用默认实现时,只允许对服务器激活的类型使用默认构造函数。若要发布其实例将使用带参数的特定构造函数创建的类型,可以使用客户端激活或者动态地发布您的特定实例。
服务器激活的对象有两种激活模式(或 WellKnownObjectMode 值):Singleton 和 SingleCall。
Singleton 类型任何时候都不会同时具有多个实例。如果存在实例,所有客户端请求都由该实例提供服务。如果不存在实例,服务器将创建一个实例,而所有后继的客户端请求都将由该实例来提供服务。由于 Singleton 类型具有关联的默认生存期,即使任何时候都不会有一个以上的可用实例,客户端也不会总接收到对可远程处理的类的同一实例的引用。
SingleCall 远程服务器类型总是为每个客户端请求设置一个实例。下一个方法调用将改由其他实例进行服务。从设计角度看,SingleCall 类型提供的功能非常简单。这种机制不提供状态管理,如果您需要状态管理,这将是一个不利之处;如果您不需要,这种机制将非常理想。也许您只关心负载平衡和可伸缩性而不关心状态,那么在这种情况下,这种模式将是您理想的选择,因为对于每个请求都只有一个实例。如果愿意,开发人员可以向 SingleCall 对象提供自己的状态管理,但这种状态数据不会驻留在对象中,因为每次调用新的方法时都将实例化一个新的对象标识。
首先对于服务端激活的两种模式来做一个试验,我们把远程对象做如下的修改:
对客户端做以下修改:using System; namespace RemoteObject { public class MyObject:MarshalByRefObject { private int i=0; public int Add(int a,int b) { return a+b; } public int Count() { return ++i; } } }
第一次打开客户端的时候显示1,第二次打开的时候显示2,类推……由此验证了Singleton 类型任何时候都不会同时具有多个实例。如果存在实例,所有客户端请求都由该实例提供服务。如果不存在实例,服务器将创建一个实例,而所有后继的客户端请求都将由该实例来提供服务。RemoteObject.MyObject app = (RemoteObject.MyObject)Activator.GetObject(typeof(RemoteObject.MyObject),System.Configuration.ConfigurationSettings.AppSettings["ServiceURL"]); Console.WriteLine(app.Count()); Console.ReadLine();
把服务器端的config修改一下:
<wellknown type="RemoteObject.MyObject,RemoteObject" objectUri="RemoteObject.MyObject" mode="SingleCall" />