為遠程對象建立客戶端
對客戶端的第一個要求是遠程對象的類要在客戶端的本機上,.Net遠程執行基礎架構代理將使用它對與遠程對象間傳遞的信息進行解釋和裝配。
需要再次建立一個通道,然後向.Net遠程基礎架構進行注冊,使該通道成為可用的:
TcpChannel myChannel = new TcpChannel();
ChannelServices.RegisterChannel(myChannel);
需要注意的是,我們在創建通道時沒有指定端口地址。我們將在要求服務器給出我們要調用的遠程對象的引用時指定端口地址,代碼如下所示:
MyCoolObject mine = (MyCoolObject)Activator.GetObject(
typeof(MyCoolObject),
"tcp://localhost:8085/MyCoolObject");
第一個參數獲取我們要定位的對象的類型,第二個參數指定遠程對象的URL。一旦我們得到該對象,就需要將其類型由普通的對象轉換為MyCoolObject類型。
現在,我們得到了位於服務器端的遠程對象的引用,我們可以將該對象看作是本地的對象。
功能強大的任務服務器
任務服務器是一個如何利用.Net的按值傳遞遠程對象機制的實例。任務服務器有一個名字為TaskRunner的對象,客戶端可以獲取它的引用,TaskRunner可以從客戶端接受任何實現ITask界面的對象。
ITask界面強迫客戶端使用Run()和Identify()二個方法創建任務對象,客戶端然後就可以創建一個復雜的、對資源敏感的實現ITask界面的任務,然後將它提交給任務服務器,在它自己的應用域中執行。這意味著沒有充足計算資源的客戶端可以充分利用任務服務器的資源執行自己無力完成的、比較復雜的任務。
因此,需要計算有3000位小數的圓周率的客戶端就可以創建一個完成相關計算和實現ITask界面的對象,該任務然後被使用TaskRunner對象提交給任務服務器執行。
ITask界面強迫客戶端從它們的Run()方法返回一個對象,當然,該對象的值可能為空,但也有可能會包含有意義的值。
簡單地說,按值傳遞的遠程執行最適合這樣一種情況,即服務器沒有客戶端希望在遠程環境中執行的對象的明確的表示。
按值傳遞對象
一個對象被按值傳遞時,它需要被轉換成一種可以傳輸的格式。一個應用域中的對象占用著一塊系統內存,而且能夠對其他對象發給它的消息作出反應。要將該對象傳遞到其他應用域中,必須將它串行化。這意味著它必須能夠被分解為字節流,然後能夠在目的地被重新組合為原來的對象。
要實現這一點,就必須使用編譯器可串行化的特性,使編譯器對一些結構進行呂行化處理。我們可以將整個類標記為可串行化的,也可以將包括一些選定的方法在內的類的一部分標記為可串行化的。在任務服務器環境中,整個的客戶端任務對象必須能夠被串行化。代碼如下所示:
Using System;
?[Serializable()]
class ClIEntTask {
?
需要注意的是,如果一個對象有外部的庫文件等附屬的部分,被該對象使用的部分也必須被串行化,這是在遠程應用域中重新建立對象所必需的。
運行例子程序
這個例子是用C# for .NET Beta 2編寫的,並在C# for .Net Beta 2中通過了測試。
為了使用任務服務器,我們必須以下面的順序對程序進行編譯:
csc /target:library /out:ITask.dll ITask.cs
csc /target:library /out:TaskRunner.dll TaskRunner.cs
csc /r:ITask.dll /r:TaskRunner.dll TaskServer.cs
csc /r:ITask.dll /r:TaskRunner.dll TaskClIEnt.cs
上面的順序非常重要,因為TaskServer和TaskClIEnt類要用到TaskRunner和ITask庫。
要運行這個例子程序,首先啟動服務器代碼,並等待出現下面的提示:
[i] Task Server Started, press to exit?
然後就可以運行客戶端程序了。
在TaskClIEnt類中有一個實現ITask界面而且能夠可串行化的類,該任務將求出二個數的積,並返回一個int類型的對象。我建議讀者創建自己的任務,並試著在任務服務器上運行它,這將使你親身體會到這種分布式計算的巨大威力。它可以使客戶端軟件開發人員充分利用任務服務器上豐富的資源完成復雜的、需要大量資源的任務。
我們可以利用任務服務器完成諸如數字處理、壓縮、加密、排序等各種操作。