Question

Please consider the following piece of code:

// 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);

How do we explain this behavior of DoCallBack?

  1. Why is the non-static method PrintDomain executed in the current domain when the Worker class is marked MarshalByRefObject?
  2. Why is the non-static method PrintDomain executed in a new AppDomain when the Worker class is marked Serializable?
  3. Why doesn't the static method need any markings?
Was it helpful?

Solution

Why is the non-static method PrintDomain executed in the current domain when the Worker class is marked MarshalByRefObject?

Because that's what MBRO does, it creates a proxy for the object that you created in your primary appdomain. Which marshals the call from the secondary appdomain to the appdomain that owns the object, the primary appdomain.

Why is the non-static method PrintDomain executed in a new AppDomain when the Worker class is marked Serializable?

Because that scenario does not use a proxy. The object itself is marshaled from the primary to the secondary appdomain. Possible because you marked it [Serializable]. The call therefore executes in the secondary appdomain.

Why doesn't the static method need any markings?

It is unclear what you mean by "markings", but it isn't any different for a static method. Some code to play with, remove the comment on the base class to compare the two scenarios:

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);
    }
}

Output as posted:

Test
Test

Output with the comments removed so the proxy is used:

ConsoleApplication1.vshost.exe
ConsoleApplication1.vshost.exe
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top