How to pass a variable from one app domain to another
Asked Answered
H

3

15

I'd like to know, if I have a variable,for example, a string, how to pass its value to my new app domain:

static string _str;

static void Main(string[] args) {
    _str = "abc";
    AppDomain domain = AppDomain.CreateDomain("Domain666");
    domain.DoCallBack(MyNewAppDomainMethod);
    AppDomain.Unload(domain);
    Console.WriteLine("Finished");
    Console.ReadKey();
}

static void MyNewAppDomainMethod() {
    Console.WriteLine(_str); //want this to print "abc"
}

Thanks

Hartebeest answered 9/8, 2009 at 4:56 Comment(0)
P
14

Use one of the variations of AppDomain.CreateDomain that takes an AppDomainSetup argument. In the AppDomainSetup object, set the AppDomainInitializerArguments member to the string array you want passed to the new app domain.

See sample code at http://msdn.microsoft.com/en-us/library/system.appdomainsetup.appdomaininitializerarguments.aspx.

With the code in the question, the change might look like (not tested):

static voide Main(string[] args) {
    _str = "abc";

    AppDomainSetup setup = new AppDomainSetup();
    setup.AppDomainInitializer = new AppDomainInitializer(MyNewAppDomainMethod);
    setup.AppDomainInitializerArguments = new string[] { _str };

    AppDomain domain = AppDomain.CreateDomain(
        "Domain666",
        new Evidence(AppDomain.CurrentDomain.Evidence),
        setup);

    Console.WriteLine("Finished");
    Console.ReadKey();
}

static void MyNewAppDomainMethod(string[] args) {
    ...
}
Padraig answered 9/8, 2009 at 5:14 Comment(3)
Thanks. Now I'd like to know how to get information back to my main appdomain. That is, return an object. Thanks!Hartebeest
And another question. I see AppDomainInitializerArguments only accepts an array of strings. In this case I really only want strings, so there is no problem, but what if I wanted other kind of data? Nothing to do about it?Hartebeest
App domains do not share an object memory space, and so passing objects around requires serialization of some sort. To return an object, you could DoCallBack on the original appdomain, if you could get your hands on it (I don't see an easy way to do so though). Alternatively, you could establish some other form of interprocess channel between the appdomains, e.g. a named pipe.Padraig
T
27

Addressing both your first and second requirements (passing through a value and retrieving another value back), here is a quite simple solution:

static void Main(string[] args)
{
    AppDomain domain = AppDomain.CreateDomain("Domain666");
    domain.SetData("str", "abc");
    domain.DoCallBack(MyNewAppDomainMethod);
    string str = domain.GetData("str") as string;
    Debug.Assert(str == "def");
}

static void MyNewAppDomainMethod()
{
    string str = AppDomain.CurrentDomain.GetData("str") as string;
    Debug.Assert(str == "abc");
    AppDomain.CurrentDomain.SetData("str", "def");
}
Tracitracie answered 25/9, 2013 at 8:36 Comment(1)
Good simple solution. Thanks. I would like to highlight that the call back function must be declared static, otherwise you are not working in new AppDomain. XCogen
P
14

Use one of the variations of AppDomain.CreateDomain that takes an AppDomainSetup argument. In the AppDomainSetup object, set the AppDomainInitializerArguments member to the string array you want passed to the new app domain.

See sample code at http://msdn.microsoft.com/en-us/library/system.appdomainsetup.appdomaininitializerarguments.aspx.

With the code in the question, the change might look like (not tested):

static voide Main(string[] args) {
    _str = "abc";

    AppDomainSetup setup = new AppDomainSetup();
    setup.AppDomainInitializer = new AppDomainInitializer(MyNewAppDomainMethod);
    setup.AppDomainInitializerArguments = new string[] { _str };

    AppDomain domain = AppDomain.CreateDomain(
        "Domain666",
        new Evidence(AppDomain.CurrentDomain.Evidence),
        setup);

    Console.WriteLine("Finished");
    Console.ReadKey();
}

static void MyNewAppDomainMethod(string[] args) {
    ...
}
Padraig answered 9/8, 2009 at 5:14 Comment(3)
Thanks. Now I'd like to know how to get information back to my main appdomain. That is, return an object. Thanks!Hartebeest
And another question. I see AppDomainInitializerArguments only accepts an array of strings. In this case I really only want strings, so there is no problem, but what if I wanted other kind of data? Nothing to do about it?Hartebeest
App domains do not share an object memory space, and so passing objects around requires serialization of some sort. To return an object, you could DoCallBack on the original appdomain, if you could get your hands on it (I don't see an easy way to do so though). Alternatively, you could establish some other form of interprocess channel between the appdomains, e.g. a named pipe.Padraig
I
7

I know that this is an old thread but perhaps this will help other people who are researching the subject.

In this article, the writer suggests using application domain SetData and GetData methods for basic exchange of data objects that support marshal-by-value or marshal-by-reference object.

Individually answered 15/6, 2011 at 21:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.