.Net Remoting Basics
.NET remoting enables you to build widely distributed applications easily, whether application components are all on one computer or spread out across the entire world. You can build client applications that use objects in other processes on the same computer or on any other computer that is reachable over its network. You can also use .NET remoting to communicate with other application domains in the same process.
To use .NET remoting to build an application in which two components communicate directly across an application domain boundary, you need to build only the following:
l A remotable object.
l A host application domain to listen for requests for that object.
l A client application domain that makes requests for that object.
Objects are valid only in the application domain where they are created. Any attempt to pass the object as a parameter or return it as a result will fail unless the object derives from MarshalByRefObject or is marked as Serializable.
There are two main kinds of remotable objects:
l Marshal-by-value (MBV) objects, which are copied and passed out of the application domain.
l Marshal-by-reference (MBR) objects, for which a proxy is created and used by the client to access the object remotely.
Marshal-by-value (MBV) objects declare their serialization rules (either by implementing ISerializable to implement their own serialization, or by being decorated with SerializableAttribute, which tells the system to serialize the object automatically) but do not extend MarshalByRefObject. The remoting system makes a complete copy of these objects and passes the copy to the calling application domain. Once the copy is in the caller's application domain, calls to the copy go directly to that copy. Further, MBV objects that are passed as arguments are also passed by value. Other than declaring the SerializableAttribute attribute or implementing ISerializable, you do not need to do anything to pass instances of your class by value across application or context boundaries.
按值传递对象就是在Client端和Server端之间复制对象。例如,Client请求Server端的MBV对象时,在整个请求完成后,对象就会同时存在Client和Server端。任何对Client端MBV对象的改变对Server端MBV对象没有影响,反之亦然。
一般而言,按值传递对象会产生性能瓶颈,特别是在Internet环境下复制大的对象。
Use MBV objects when it makes sense for performance or processing reasons to move the complete state of the object and any executable functionality to the target application domain. In many scenarios, this reduces lengthy, resource-consuming round trips across network, process, and application domain boundaries. MBV objects are also used directly from within the object's original application domain. In this case, because no marshaling takes place, no copy is made and access is very efficient.
.Net Remoting框架内在支持对象的序列化/反序列化。你仅需要标识对象[Serializable]属性或者实现ISerializable接口,.Net Remoting负责其余的工作。这样就允许通过XML格式跨平台传递对象。不过,要注意有些对象并不支持Serializable序列化。如DataReader(SqlDataReader或OleDbDataReader)类,因为DataReader类必须保持到数据库的连接,所以它们不能被序列化到XML中。
如果正在序列化的对象图中的任何类型未应用SerializableAttribute属性,公共语言运行库CLR则会引发SerializationException异常。
默认情况下,类型中由SerializableAttribute标记的所有公共和私有字段都会进行序列化,除非该类型实现ISerializable接口来重写序列化进程(通过实现该接口可以实现"自定义序列化")。默认的序列化进程会排除用NonSerializedAttribute属性标记的字段,即你可以将该类型标记为[NonSerialized()]以表明它是不可以被序列化的。如果可序列化类型的字段包含指针、句柄或其他某些针对于特定环境的数据结构,并且不能在不同的环境中以有意义的方式重建,则最好将NonSerializedAttribute属性应用于该字段。无法序列化的本地对象将不能传递到其他应用程序域中,因而也不能远程处理。
Marshal-by-reference (MBR) objects are remotable objects that extend at least System.MarshalByRefObject. Depending on what type of activation has been declared, when a client creates an instance of an MBR object in its own application domain, the .NET remoting infrastructure creates a proxy object in the caller's application domain that represents the MBR object, and returns to the caller a reference to that proxy. The client then makes calls on the proxy. Remoting marshals those calls, sends them back to the originating application domain, and invokes the call on the actual object.
MarshalByRefObject实际对象只存在于Server端,仅有一个所谓的ObjRef对象传送到Client端。
Note If the client is in the same application domain as the MBR object, the infrastructure returns to the client a direct reference to the MBR object, avoiding the overhead of marshaling.
If a MarshalByRefObject is passed as a parameter, it becomes a proxy in the other application domain when the call arrives. MBR return values and out parameters work in the same way.
You should use MBR objects when the state of the object and any executable functionality should stay in the application domain in which it was created. For example, an object that has an internal field that is an operating system handle should extend MarshalByRefObject because the operating system handle would not be meaningful in another application domain, in another process, or on another computer. Sometimes an object can also be prohibitively large; that might work on a robust server, but not when sent over a wire to a 33.6 kbps modem.
Reference:
1. Ingo Rammer, Advanced .Net Remoting.
2. David Conger, Remoting with C# and .Net.
3. Microsoft MSDN.