C#中的遠程執(zhí)行和分布式計算_第1頁
C#中的遠程執(zhí)行和分布式計算_第2頁
C#中的遠程執(zhí)行和分布式計算_第3頁
C#中的遠程執(zhí)行和分布式計算_第4頁
C#中的遠程執(zhí)行和分布式計算_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

1、C#中的遠程執(zhí)行和分布式計算摘要 遠程執(zhí)行是C#中一種使開發(fā)人員能夠使用遠程對象的基礎架構(gòu)。遠程對象是一種位于調(diào)用者應用域之外的對象。本文中的例子說明了如何使用二種遠程對象訪問機制(值傳遞和地址傳遞),它還通過一個簡單的、功能強大的任務服務器的實現(xiàn)說明了分布式計算中遠程對象的強大功能。 任務服務器能夠接受所有能實現(xiàn)ITask界面的對象,并在其應用域中運行這些對象。更為重要的是,它能夠一次從多個客戶端接受任務。 在學習完本篇文章后,讀者將能夠: 建立服務器/客戶端對象之間的連接。 按值傳遞對象。 按地址傳遞對象。 理解遠程任務分配的概念。 遠程對象 遠程對象通過地址傳遞對象或者通過對象的值傳遞對

2、象。 在第一種情況下,對象的地址由應用域A傳遞到應用域B,但對象的方法調(diào)用在應用域A和應用域B之間。對象在應用域A中存在和運行,但在應用域B中也象是個本地的對象。 在第二種情況下,整個對象及其附屬的實體(被稱作對象圖表)被串行化成字節(jié)的形式,并從應用域A被傳送到應用域B。然后,對象在應用域B被“反串行化”并恢復到原來的狀態(tài)?,F(xiàn)在,對象就在應用域B上存在和運行了。 建立對象主機(也被稱作服務器) 設立服務器需要作的第一步是在對象進行通訊的二個應用域間建立一條通道,它可以是一條TCP/IP通道或HTTP通道。TCP通道的速度較快,適用于對網(wǎng)絡內(nèi)信息包傳輸限制較少的網(wǎng)絡使用,HTTP通道更靈活,適合

3、在互聯(lián)網(wǎng)等廣域網(wǎng)上使用。 我們將使用TCP/IP通道,而且將在同一臺機器的二個不同的應用域名上同時運行服務器端和客戶機端。因此,輸入下面的代碼在TCP/IP堆棧上的8065端口創(chuàng)建通道m(xù)yChannel: TcpChannel myChannel = new TcpChannel(8065); 下面是向.NET的通道服務注冊myChannel通道,這將使該通道可以在服務器應用域之外被訪問。我們可以通過下面的代碼實現(xiàn)這一目的: ChannelServices.RegisterChannel(myChannel); 最后一步是告訴.NET的遠程執(zhí)行基礎架構(gòu)有關我們要開放的對象的有關情況,我們需要公

4、布對象的類型和位置,客戶端定位對象所使用的名稱和.NET的遠程基礎架構(gòu)對對這一對象調(diào)用的處理方式。我們可以通過下面的代碼獲取對象的類型: Type objectType = new MyCoolObject().GetType() 通過下面的代碼就可以向.NET遠和基礎架構(gòu)注冊該對象: RemotingConfiguration.RegisterWellKnownServiceType( objectType, "MyCoolObject", WellKnownObjectMode.Singleton); 對象的調(diào)用有二種處理方式:Singleton和SingleCall。

5、在Singleton方式中,在第一次客戶端方法調(diào)用時創(chuàng)建對象,并保持對象存在直到客戶端中止連接或?qū)ο笞匀凰劳?;在SingleCall方式中,每次客戶端的方法調(diào)用都會創(chuàng)建對象,對象只在方法調(diào)用持續(xù)期間存在,一旦方法調(diào)用結(jié)束,對象就會死亡。SingleCall方式中,客戶端連接不會隨方法調(diào)用的結(jié)束而中止,只有對象會隨著方法調(diào)用的結(jié)束而被殺死。為遠程對象建立客戶端 對客戶端的第一個要求是遠程對象的類要在客戶端的本機上,.NET遠程執(zhí)行基礎架構(gòu)代理將使用它對與遠程對象間傳遞的信息進行解釋和裝配。 需要再次建立一個通道,然后向.NET遠程基礎架構(gòu)進行注冊,使該通道成為可用的: TcpChannel my

6、Channel = new TcpChannel(); ChannelServices.RegisterChannel(myChannel); 需要注意的是,我們在創(chuàng)建通道時沒有指定端口地址。我們將在要求服務器給出我們要調(diào)用的遠程對象的引用時指定端口地址,代碼如下所示: MyCoolObject mine = (MyCoolObject)Activator.GetObject( typeof(MyCoolObject), "tcp:/localhost:8085/MyCoolObject"); 第一個參數(shù)獲取我們要定位的對象的類型,第二個參數(shù)指定遠程對象的URL。一旦我們得

7、到該對象,就需要將其類型由普通的對象轉(zhuǎn)換為MyCoolObject類型。 現(xiàn)在,我們得到了位于服務器端的遠程對象的引用,我們可以將該對象看作是本地的對象。 功能強大的任務服務器 任務服務器是一個如何利用.NET的按值傳遞遠程對象機制的實例。任務服務器有一個名字為TaskRunner的對象,客戶端可以獲取它的引用,TaskRunner可以從客戶端接受任何實現(xiàn)ITask界面的對象。 ITask界面強迫客戶端使用Run()和Identify()二個方法創(chuàng)建任務對象,客戶端然后就可以創(chuàng)建一個復雜的、對資源敏感的實現(xiàn)ITask界面的任務,然后將它提交給任務服務器,在它自己的應用域中執(zhí)行。這意味著沒有充足

8、計算資源的客戶端可以充分利用任務服務器的資源執(zhí)行自己無力完成的、比較復雜的任務。 因此,需要計算有3000位小數(shù)的圓周率的客戶端就可以創(chuàng)建一個完成相關計算和實現(xiàn)ITask界面的對象,該任務然后被使用TaskRunner對象提交給任務服務器執(zhí)行。 ITask界面強迫客戶端從它們的Run()方法返回一個對象,當然,該對象的值可能為空,但也有可能會包含有意義的值。 簡單地說,按值傳遞的遠程執(zhí)行最適合這樣一種情況,即服務器沒有客戶端希望在遠程環(huán)境中執(zhí)行的對象的明確的表示。 按值傳遞對象 一個對象被按值傳遞時,它需要被轉(zhuǎn)換成一種可以傳輸?shù)母袷?。一個應用域中的對象占用著一塊系統(tǒng)內(nèi)存,而且能夠?qū)ζ渌麑ο蟀l(fā)給

9、它的消息作出反應。要將該對象傳遞到其他應用域中,必須將它串行化。這意味著它必須能夠被分解為字節(jié)流,然后能夠在目的地被重新組合為原來的對象。 要實現(xiàn)這一點,就必須使用編譯器可串行化的特性,使編譯器對一些結(jié)構(gòu)進行呂行化處理。我們可以將整個類標記為可串行化的,也可以將包括一些選定的方法在內(nèi)的類的一部分標記為可串行化的。在任務服務器環(huán)境中,整個的客戶端任務對象必須能夠被串行化。代碼如下所示: Using System; ?Serializable() class ClientTask ? 需要注意的是,如果一個對象有外部的庫文件等附屬的部分,被該對象使用的部分也必須被串行化,這是在遠程應用域中重新建立

10、對象所必需的。運行例子程序 這個例子是用C# for .NET Beta 2編寫的,并在C# for .NET Beta 2中通過了測試。 為了使用任務服務器,我們必須以下面的順序?qū)Τ绦蜻M行編譯: 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 上面的順序

11、非常重要,因為TaskServer和TaskClient類要用到TaskRunner和ITask庫。 要運行這個例子程序,首先啟動服務器代碼,并等待出現(xiàn)下面的提示: i Task Server Started, press to exit? 然后就可以運行客戶端程序了。 在TaskClient類中有一個實現(xiàn)ITask界面而且能夠可串行化的類,該任務將求出二個數(shù)的積,并返回一個int類型的對象。我建議讀者創(chuàng)建自己的任務,并試著在任務服務器上運行它,這將使你親身體會到這種分布式計算的巨大威力。它可以使客戶端軟件開發(fā)人員充分利用任務服務器上豐富的資源完成復雜的、需要大量資源的任務。 我們可以利用任務

12、服務器完成諸如數(shù)字處理、壓縮、加密、排序等各種操作。 正面是本文中例子所涉及的源代碼,及其簡單的注解,供有興趣的讀者參考: / ITask.cs / 用戶可以使用該界面來創(chuàng)建自己的任務,它完成下面的二種操作: / ·服務器可以通過調(diào)用方法Run()來運行建立的任務。 / ·客戶端可以保證任務從方法Run()中啟動。 / 其中還有一個Identify()方法,服務器用它顯示一些有關任務的信息。 / 該界面被編譯為同一個名字空間下的單獨的庫文件,使得任務服務器的管理員能夠?qū)⒃摻缑孀鳛樗心軌蛟?他的任務服務器上運行的任務的契約進行分發(fā)。 / 客戶端將繼承該類,創(chuàng)建自己的任務對象

13、,提交給服務器運行。 namespace TaskServer / 必須將它定義為一個界面 public interface ITask object Run(); string Identify(); / TaskRunner.cs / 該對象用來運行由客戶端提交的任務,提交的任務將在服務器的應用域執(zhí)行。 / TaskRunner對象以引用的方式傳遞給客戶端,無需對它進行串行化 / TaskRunner接受所有實現(xiàn)ITask界面的任務,它需要二個參數(shù):Run()和Identify()。 using System; using System.Runtime.Remoting; using Sy

14、stem.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace TaskServer public class TaskRunner : MarshalByRefObject ITask remoteTaskObject; public TaskRunner() Console.WriteLine("ni TaskRunner activated"); public string LoadTask(ITask task) Console.WriteLine("

15、;ni Loading new task."); if(task = null) Console.WriteLine("e Task reference is NULL. Task not Loaded."); return "e Task not loaded." remoteTaskObject = task; Console.WriteLine("i Task has been loaded."); Console.WriteLine("i Task ID: " + remoteTaskObject

16、.Identify() + "n"); return "i Task loaded. Welcome to the All Powerful TaskServer." public object RunTask() Console.WriteLine("ni Running the task."); object result = remoteTaskObject.Run(); Console.WriteLine("i Task finished."); return result; / TaskServerEng

17、ine.cs / 這個類用來啟動任務服務器應用程序。它建立C#遠程執(zhí)行的后端,加載通道,注冊TaskRunner對象,然后讓 /遠程執(zhí)行機制的后端監(jiān)測TCP通道上的連接請求 using System; using System.IO; / 下面的庫用于向遠程執(zhí)行機制注冊我們的對象 using System.Runtime.Remoting; / 下面的庫用于向通道服務注冊我們的TCP通道設備 using System.Runtime.Remoting.Channels; / 該庫提供了用來與遠程應用域(客戶端)通訊所需要的TCP通道 using System.Runtime.Remoting.

18、Channels.Tcp; namespace TaskServer public class TaskServerEngine / 我們只需要一個方法,它可以是靜態(tài)的,因為我們不需要建立這個類的實例,該方法的作用僅僅是 /創(chuàng)建并創(chuàng)始化TaskServerEngine。 public static void Main() / 向用戶表明我們正在啟動服務器類 Console.WriteLine("The All Powerful Task Server!"); Console.WriteLine("."Your Task is My Command&quo

19、t;."); Console.WriteLine("ni Starting Task Server."); try / 創(chuàng)建TCP通道 Console.WriteLine("i - Creating TCP channel"); TcpChannel chan = new TcpChannel(8085); / 向.NET的遠程服務注冊新創(chuàng)建的TcpChannel,使客戶端可以使用這一服務 Console.WriteLine("i - Registering TCP channel"); ChannelServices.Re

20、gisterChannel(chan); /向遠程機制的后端注冊TaskRunner對象,RegisterWellKnownServiceType方法將完成這一 /操作,并接收下面的參數(shù): / *內(nèi)容為TaskRunner對象映象的類型對象 / * 向客戶公布的服務名字 / * 對象的模式:Singleton意味著所有客戶端請求共享一個對象服務;SingleCall意味著 / 每個客戶端請求使用一個新的對象服務。 Console.WriteLine("i - Registering the TaskRunner object"); Type theType = new Ta

21、skRunner().GetType(); RemotingConfiguration.RegisterWellKnownServiceType(theType, "TaskServer", WellKnownObjectMode.Singleton); Console.WriteLine("i Task Server started, press to exit."); Console.ReadLine(); catch (Exception e) Console.WriteLine("! An error occured while ini

22、tialising the TaskServerEngine."); Console.WriteLine(e); / TaskClient.cs / 這是一個客戶端應用域,客戶端的任務是建立一個任務對象,并將它提交給任務服務器 using System; / 建立與任務服務器的連接所必需的庫文件 using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using TaskServer; namespace Hap

23、pyClientWithTask Serializable() / 下面是我們創(chuàng)建的任務 class ClientTask : ITask private int num1, num2; private int result; public ClientTask(int num1, int num2) this.num1 = num1; this.num2 = num2; public object Run() result = num1 * num2; return (object)result; public string Identify() return("I am a mu

24、ltiplication task."); public class Client public static void Main() Console.WriteLine("nWelcome to the humble, lowly client Application Domain.n"); ClientTask clientTask = new ClientTask(100,100); try Console.WriteLine("i Connecting to TaskServer."); Console.WriteLine("

25、i - Opening TCP Channel"); TcpChannel chan = new TcpChannel(); Console.WriteLine("i - Registering the channel"); ChannelServices.RegisterChannel(chan); Console.WriteLine("i Connected to TaskServer"); / 從TaskServer中獲取TaskRunner對象的引用 / Activator類中的GetObject方法需要二個參數(shù): / * 對象類型 / * 對象的URI位置 Console.WriteLine("i Getting a reference to the TaskRunner Object&quo

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論