.Net組件程序設計之遠程調用(一)

 .Net組件程序設計之遠程調用(一)app

1應用程序域

咱們知道咱們寫的C#代碼是在操做系統邏輯體系結構中最上層的,然而操做系統自己是不會認識C#代碼的,它只認識機器代碼。那咱們寫的程序通過編譯後是編譯成IL的,是怎麼運行的呢?實際是在一個託管的環境下運行的,是.NET提供的支持,操做系統是不會識別IL的,這中間就須要一個橋樑:應用程序域。操做系統中的進程是資源單位,應用程序域的執行使用固然也要佔用空間使用資源了,因此是物理進程承載着應用程序域的,並且這種承載關係並非一對一的。框架

圖:應用程序域分佈式

使用應用程序域這樣的機制,是有許多好處的。好比說客戶端在調用其餘組件的時候能夠建立一個應用程序域,而後在新建的應用程序域中加載組件進行操做等等,即便被調用的組件發生一些致命的錯誤也不會致使客戶端崩潰,有效的進行了錯誤隔離。還有一些數據交互傳輸上的性能差別等等,這裏不作詳細的闡述了。函數

2.NET Remoting

.NET Remoting是一種基於.NET平臺的分佈式系統框架,所瞭解的就是用於數據傳輸。 說幾句它被使用的侷限性很大,受到了平臺的限制,固然若是僅僅是這樣是不可否定它的強大和幾乎無限擴展的框架體系,不管在哪個環節你均可以本身來實現一些自定義的功能。會在下個篇幅稍做講解。性能

3.AppDomain

在.NET中用AppDoMain類來表示應用程序域,也提供了獲取當前應用程序域的方法,能夠直接使用AppDoMain類的靜態屬性CurrentDomain來獲取到當前程序所在的應用程序域,這是一種方法,還額外提供一種了,就是Thread類的GetDomain()靜態方法也是能夠獲取到的。優化

3.1 在當前應用程序域中建立對象

 1 namespace RemoteServer
 2   public class class1
 3     {
 4         private string appDoMainName;
 5 
 6         public class1()
 7         {
 8             appDoMainName = AppDomain.CurrentDomain.FriendlyName;
 9         }
10 
11         public void Writer()
12         {
13             Console.WriteLine(appDoMainName);
14         }
15     }

class1中構造函數是獲取當前應用程序域的名稱,而且是在Writer()方法中輸出到控制檯界面中,spa

using RemoteServer;

namespace RemoteCase
{
            AppDomain appDoMain = AppDomain.CurrentDomain;
            class1 cls1 = (class1)appDoMain.CreateInstanceFromAndUnwrap("RemoteServer.dll", "RemoteServer.class1");
            cls1.Writer();
}

圖3-1操作系統

這裏使用了AppDomain中的靜態方法CreateInstanceFromAndUnwrap(),由於當前項目已經引用了RemoteServer程序集,因此第一個參數只是一個顯示的名稱,並非全路徑,在調用方法的時候,應用程序域會加載程序集,用於獲取到元數據。設計

3.2 在新建應用程序域中建立對象

 1 namespace RemoteServer
 2       public class class1:MarshalByRefObject
 3       {
 4         private string appDoMainName;
 5 
 6         public class1()
 7         {
 8             appDoMainName = AppDomain.CurrentDomain.FriendlyName;
 9         }
10 
11         public void Writer()
12         {
13             Console.WriteLine(appDoMainName);
14         }
15       }
1 using RemoteServer;
2 
3       AppDomain appDoMain = AppDomain.CurrentDomain;
4       AppDomain newDoMain = AppDomain.CreateDomain("NewDoMain");
5       class1 cls1 = (class1)newDoMain.CreateInstanceFromAndUnwrap("RemoteServer.dll", "RemoteServer.class1");
6       cls1.Writer();

圖3-2
代理

3.3 拆包遠程對象

圖3-3-1

這段代碼是3.2中的代碼,cls1並非class1類型自己,而是代理,訪問遠程對象都是經過代理完成的,這麼屌炸天的.NET固然提供優化,將建立遠程對象和在客戶端創建代理分離,這樣能夠在你建立了一個遠程對象以後再創建代理。 AppDomain類提供了一套CreateInstance()方法來建立對象,可是都以ObjectHandle的形式返回一個遠程對象句柄(意思就是遠程對象的惟一標示,這個句柄能表明遠程對象)

ObjectHandle對象實現了System.Runtime.Remoting命名空間下的IObjectHandle接口:

 1 namespace RemoteServer
 2 public class class1:MarshalByRefObject
 3     {
 4         private string appDoMainName;
 5 
 6         public class1()
 7         {
 8             appDoMainName = AppDomain.CurrentDomain.FriendlyName;
 9         }
10 
11         public void Writer()
12         {
13             Console.WriteLine(appDoMainName);
14         }
15 
16     }
 1 using RemoteServer;
 2 
 3             AppDomain appDoMain = AppDomain.CurrentDomain;
 4             AppDomain newDoMain = AppDomain.CreateDomain("NewDoMain");
 5             IObjectHandle objecthandle;
 6             objecthandle = newDoMain.CreateInstance("RemoteServer", "RemoteServer.class1");
 7 
 8             RemoteServer.class1 cls1 = objecthandle.Unwrap() as RemoteServer.class1;
 9 
10             cls1.Writer();

通常狀況下是不須要手動拆包對象句柄的,這樣作的好處只是能夠推遲加載RemoteServer程序集,只有在 objecthandle.Unwrap()的時候纔會創建代理,而創建代理必須須要對象元數據。

4遠程對象類型

通常狀況下,被引用對象和客戶端同在一個應用程序域,這樣的狀況下不涉及到代理,也不會用到什麼遠程調用,

而是直接引用對象,若是當你須要調用另外一個應用程序域裏的對象時會是什麼樣的?默認狀況下.NET是不容許對象跨應用程序域訪問的,

不論是不是在同一個進程內。可是呢若是要訪問,也不是不行的,.NET提供了兩種數據傳遞方式,一種是值傳遞,一種是引用傳遞

4.1按值封送

   當應用程序域A調用應用程序域B中的對象時,應用程序域B中的對象會被拷貝一個克隆到應用程序域A,這時候兩個對象是不存在任何關係的,這種狀況叫作按值封送    通常狀況下都是使類型使用Serializable特性,支持序列化,經過序列化來達到按值封送的目的,在被調用方序列化,到調用方反序列化。

4.2引用封送

   這種狀況就是當應用程序域A調用應用程序域B的對象時,應用程序域A得到的是應用程序域B中對象的引用,

這個引用掛在哪裏呢?掛在應用程序域A的對象代理上,這種狀況就叫引用封送    引用封送就比按值封送有意思多了,想要知足能夠引用封送的要求,則對象必須繼承自MarshalByRefObject,MarshalByRefObject類型給出的解釋就是 容許在支持遠程處理的應用程序中跨應用程序域邊界訪問對象,這樣做爲它的子類一樣的也享受這樣的優待。在引用封送中會有兩種遠程對象激活模式,這個內容在下一個篇幅中會有詳細的示例代碼。

 

 

 

做者:金源

出處:http://www.cnblogs.com/jin-yuan/

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面

相關文章
相關標籤/搜索