標籤:catch lin register test c99 currently 包含 分享 fail
JointCode.Shuttle 是一個用於進程內 AppDomain 間通訊的服務架構(不支援跨進程)。
本文通過一個簡單的樣本來示範如何使用 JointCode.Shuttle。
JointCode.Shuttle 的發行包
在 JointCode.Shuttle 的發行包中,包含兩個檔案:JointCode.Shuttle.dll 和 JointCode.Shuttle.Library.dll,其中 JointCode.Shuttle.dll 是使用託管語言編寫的庫檔案,JointCode.Shuttle.Library.dll 則是前者依賴的、使用非託管語言編寫的一個組件。
準備工作
要使用 JointCode.Shuttle,我們首先需要在項目中引用 JointCode.Shuttle.dll 這個程式集,同時要把 JointCode.Shuttle.Library.dll 複製到項目編譯之後 JointCode.Shuttle.dll 所在的檔案夾中(例如,假設項目編譯後,JointCode.Shuttle.dll 被複製到 c:/projects/sampleproject 檔案夾中,則需要手動將 JointCode.Shuttle.Library.dll 複製到此檔案夾)。
開始編碼
JointCode.Shuttle 是面向介面編程的,所以我們首先需要編寫一個服務介面(也叫服務契約),並對其應用 ServiceInterface 屬性。
1 [ServiceInterface]2 public interface ISimpleService3 {4 string GetOutput(string input);5 }View Code
接著編寫一個實現該契約的服務類,並對其應用 ServiceClass 屬性。
1 [ServiceClass(typeof(ISimpleService), Lifetime = LifetimeEnum.Transient)] 2 public class SimpleService : ISimpleService 3 { 4 public string GetOutput(string input) 5 { 6 return string.Format 7 ("SimpleService.GetOutput says: now, we are running in AppDomain: {0}, and the input passed from the caller is: {1}", 8 AppDomain.CurrentDomain.FriendlyName, input); 9 }10 }View Code
由於要實現跨 AppDomain 通訊,因此這裡我們需要編寫一個用於啟動遠程服務的類,並讓該類繼承自 MarshalByRefObject。
1 public class ServiceProvider : MarshalByRefObject 2 { 3 // 這裡必須使用一個欄位來持有 ShuttleDomain 執行個體的引用,因為如果該執行個體被記憶體回收, 4 // 那麼通過該執行個體註冊的所有服務也會被登出 5 ShuttleDomain _shuttleDomain; 6 7 public void RegisterServices() 8 { 9 // 註冊服務組時,需要傳遞一個 Guid 對象10 var guid = new Guid();11 _shuttleDomain.RegisterServiceGroup(ref guid,12 new ServiceTypePair(typeof(ISimpleService), typeof(SimpleService)));13 }14 15 public void CreateShuttleDomain()16 {17 // 建立一個 ShuttleDomain18 _shuttleDomain = ShuttleDomainHelper.Create("domain1", "domain1");19 }20 21 public void DisposeShuttleDomain()22 {23 _shuttleDomain.Dispose();24 }25 }View Code
現在,可以開始使用 JointCode.Shuttle 了。有關使用方法,可以參見注釋,代碼如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 // 要使用 JointCode.Shuttle,首先必須初始化 ShuttleDomain。 6 // 這個初始化操作一般在預設 AppDomain 執行,但也可以在其他 AppDomain 中執行,都是一樣的。 7 ShuttleDomain.Initialize(); 8 9 // 在預設 AppDomain 中建立一個子 AppDomain,並在該 AppDomain 中建立一個 ServiceProvider 對象。10 var serviceEnd1Domain = AppDomain.CreateDomain("ServiceEndDomain1", null, null);11 var serviceProvider = (ServiceProvider)serviceEnd1Domain.CreateInstanceAndUnwrap12 (typeof(Program).Assembly.FullName, "JoitCode.Shuttle.SimpleSample.ServiceProvider");13 14 // 在子 AppDomain 中,建立一個 ShuttleDomain 執行個體。15 serviceProvider.CreateShuttleDomain();16 17 // 在子 AppDomain 中,註冊 ISimpleService 服務。18 serviceProvider.RegisterServices();19 20 // 在預設 AppDomain 中,建立一個 ShuttleDomain。21 // 事實上,在應用程式的每個 AppDomain 中都需要有一個 ShuttleDomain 對象。22 // 該對象用於與其他 AppDomain 中的 ShuttleDomain 對象通訊。23 var str = Guid.NewGuid().ToString();24 var shuttleDomain = ShuttleDomainHelper.Create(str, str);25 26 // 在預設 AppDomain 中,擷取子 AppDomain 中註冊的服務執行個體。27 // 目前服務執行個體的預設生存期為 1 分鐘。每次調用服務方法時,服務執行個體的生存期延長 30 秒。28 ISimpleService service;29 if (shuttleDomain.TryGetService(out service))30 {31 try32 {33 Console.WriteLine("Currently, we are running in AppDomain {0} before calling the remote service method...", 34 AppDomain.CurrentDomain.FriendlyName);35 36 Console.WriteLine();37 // 調用子 AppDomain 中註冊的 ISimpleService 服務執行個體的服務方法。38 var output = service.GetOutput("China");39 Console.WriteLine(output);40 41 Console.WriteLine();42 Console.WriteLine("Tests completed...");43 }44 catch45 {46 Console.WriteLine();47 Console.WriteLine("Failed to invoke the remote service method...");48 }49 }50 else51 {52 Console.WriteLine();53 Console.WriteLine("Failed to create remote service instance...");54 }55 56 // 立即釋放子 AppDomain 中產生的 ISimpleService 服務執行個體,而不用等待其生存期結束。57 // 此為可選操作,因為即使不手動釋放 ISimpleService 服務執行個體,在其生命期結束之時系統也會自動釋放該執行個體58 //(如果 ISimpleService 實現了 IDisposable,還會調用其 Dispose 方法)59 shuttleDomain.ReleaseService(service);60 61 // 在子 AppDomain 中,釋放緩衝的 ShuttleDomain 執行個體。這將會登出通過該執行個體註冊的所有服務(在本樣本中,即 ISimpleService 服務)。62 serviceProvider.DisposeShuttleDomain();63 64 Console.Read();65 }66 }
如需完整代碼,請點擊 此處 下載。
使用 JointCode.Shuttle 進行跨 AppDomain 通訊的一個簡單樣本