2013-05-16 62 views
6

請考慮下面的代碼:DoCallBack CrossAppDomainDelegate行爲非靜態代表

// Create a new application domain 
AppDomain ad = AppDomain.CreateDomain("New domain"); 

Worker work = new Worker(); 

// if Worker class is marked as 'MarshalByRefObject', this will run in current 
// appdomain. 
// if Worker class is NOT marked as 'MarshalByRefObject' and is marked as 
// 'Serializable', this will run in a new appdomain. 
ad.DoCallBack(work.PrintDomain); 
// or ad.DoCallBack(new CrossAppDomainDelegate(work.PrintDomain)); 

// But for static methods: 
// If ppp method is static, no marking is required and it will run in 
// a new AppDomain. 
ad.DoCallBack(Worker.ppp); 

我們如何解釋的DoCallBack這種行爲?

  1. 爲什麼非靜態方法PrintDomain在當前域中執行時Worker類被標記MarshalByRefObject
  2. 爲什麼在Worker類標記爲Serializable時,在新的AppDomain中執行非靜態方法PrintDomain
  3. 爲什麼靜態方法不需要任何標記?

回答

6

爲什麼PrintDomain非靜態方法在當前域中執行時,工人類被標記MarshalByRefObject的?

因爲這就是MBRO所做的,它會爲您在主AppDomain中創建的對象創建一個代理。將從輔助應用程序域調用到擁有該對象(主要應用程序域)的應用程序域的調用。

爲什麼當Worker類標記爲Serializable時,在新的AppDomain中執行非靜態方法PrintDomain?

因爲該場景確實是而不是請使用代理。對象本身從主要應用程序封裝到次要應用程序域。可能是因爲你標記了[Serializable]。因此,該調用在輔助appdomain中執行。

爲什麼靜態方法不需要任何標記?

目前還不清楚「標記」是什麼意思,但它對靜態方法沒有任何不同。一些代碼一起玩,去除基類的註釋來比較兩種方案:

using System; 

class Program { 
    static void Main(string[] args) { 
     var dom = AppDomain.CreateDomain("Test"); 
     var obj = new WorkerMbro(); 
     dom.DoCallBack(obj.PrintDomain); 
     dom.DoCallBack(obj.PrintDomainStatic); 
     Console.ReadLine(); 
    } 
} 
[Serializable] 
class WorkerMbro /* : MarshalByRefObject */ { 
    public void PrintDomain() { 
     Console.WriteLine(AppDomain.CurrentDomain.FriendlyName); 
    } 
    public void PrintDomainStatic() { 
     Console.WriteLine(AppDomain.CurrentDomain.FriendlyName); 
    } 
} 

輸出發佈:

Test 
Test 

輸出與評論移除,以便使用代理:

ConsoleApplication1.vshost.exe 
ConsoleApplication1.vshost.exe 
+1

您的方法'PrintDomainStatic'不是靜態的。當使用代理('MarshalByRefObject'取消註釋)輸出是'ConsoleApplication1.vshost.exe測試' – Troopers