Discussion:
Calling host AppDomain from new AppDomain
(too old to reply)
okaminer
2008-11-26 07:41:13 UTC
Permalink
Hi
I know how to create a new AppDomain and send request to that
AppDomain using MarshalByRefObject
But how can I call the hosting AppDomain from the new AppDomain

This is my code code for creating and calling a new AppDomain:

AppDomain newDomain = AppDomain.CreateDomain("NewDomain");
MyClass cls = (MyClass)newDomain.CreateInstanceAndUnwrap
("TestAppDomain", "MyRemoteClass.MyClass");
cls.MyRemoteEvent += new EventHandler(cls_MyRemoteEvent);
cls.DoSomething();

Now the MyClass (cls) do bunch of stuff in the DoSomething function
(where a new thread is created) and every now and then needs to pass
information back to the First AppDomain
so how can I accomplish that?

Thank in advance
Jeroen Mostert
2008-11-26 19:00:44 UTC
Permalink
Post by okaminer
I know how to create a new AppDomain and send request to that
AppDomain using MarshalByRefObject
But how can I call the hosting AppDomain from the new AppDomain
In the exact same way. Use serializable objects.
Post by okaminer
AppDomain newDomain = AppDomain.CreateDomain("NewDomain");
MyClass cls = (MyClass)newDomain.CreateInstanceAndUnwrap
("TestAppDomain", "MyRemoteClass.MyClass");
cls.MyRemoteEvent += new EventHandler(cls_MyRemoteEvent);
cls.DoSomething();
Now the MyClass (cls) do bunch of stuff in the DoSomething function
(where a new thread is created) and every now and then needs to pass
information back to the First AppDomain
so how can I accomplish that?
Pass a delegate to the remote class. You're already doing that with the
MyRemoteEvent event handler (which uses delegates under the covers). So you
could have, for example:

cls.DoSomething(passInformationBack);

...

void passInformationBack(Information i) {
...
}

class MyClass {
public void DoSomething(Action<Information> passInformationBack) {
... do something ...
passInformationBack(new Information(...));
}
}

Take care that any functions called this way must only use serializable
arguments (either marked with [Serializable] or being MBROs). In the example
above, this applies to the Information class. Also, keep in mind that
there's a hefty performance penalty associated with remoting, so take care
to minimize the number of remote calls needed.
--
J.
okaminer
2008-11-29 08:33:45 UTC
Permalink
Great thanks for the quick reply
okaminer
2008-11-30 09:20:26 UTC
Permalink
Hi
I've tried what you've suggested
I've passed a delegate to the function but when i call that delegate
the function runs under the second Domain (new domain) and not the
host domain
This is the code

//Call back delegate
public delegate void CallBackDelegate(string str);
//Proxy class
public class ProxyClass:MarshalByRefObject
{
public void DoSomething(string str, CallBackDelegate callback)
{

System.Diagnostics.Debug.WriteLine(str + " from domain " +
AppDomain.CurrentDomain.Id);
//This function is called in the new AppDomain
callback("My Value");

}
}
Jeroen Mostert
2008-11-30 12:36:42 UTC
Permalink
Post by okaminer
I've tried what you've suggested
I've passed a delegate to the function but when i call that delegate
the function runs under the second Domain (new domain) and not the
host domain
This is the code
//Call back delegate
public delegate void CallBackDelegate(string str);
//Proxy class
public class ProxyClass:MarshalByRefObject
{
public void DoSomething(string str, CallBackDelegate callback)
{
System.Diagnostics.Debug.WriteLine(str + " from domain " +
AppDomain.CurrentDomain.Id);
//This function is called in the new AppDomain
callback("My Value");
You don't show the code that passes "callback", but whatever object the
delegate is referring to must be a MarshalByRefObject created in the first
AppDomain for the execution context to change. If it's serializable, the
object will just be copied over to the new domain. Here's a complete sample:

class NewDomainObject : MarshalByRefObject {
public void DoCallback(Action callback) {
Console.WriteLine("NewDomainObject executing in domain " +
AppDomain.CurrentDomain.FriendlyName);
callback();
}
}

class OldDomainObject : MarshalByRefObject {
public void PrintDomain() {
Console.WriteLine("OldDomainObject executing in domain " +
AppDomain.CurrentDomain.FriendlyName);
}
}

class Program {
static void Main(string[] args) {
var newDomain = AppDomain.CreateDomain("New domain");
var oldDomainObject = new OldDomainObject();
var newDomainObject = (NewDomainObject)
newDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName,
typeof(NewDomainObject).FullName);
newDomainObject.DoCallback(oldDomainObject.PrintDomain);
}
}

If you just need an isolated piece of code to execute in another AppDomain,
you can also consider using AppDomain.DoCallBack(), but this approach is
simpler.
--
J.
okaminer
2008-12-02 09:22:30 UTC
Permalink
Great this works perfectlly :-)

Loading...