Tuesday, July 15, 2014

app domains

Hi,

today I wanted to create a launcher application to launch my other wpf applications. This sounds easy but is really hard because you can have only 1 application object in an application domain. The task to do seemed to be clear... I needed a second application domain. But first I researched a little bit about application domains and want to show here some quotes to this:

Operating systems and runtime environments typically provide some form of isolation between applications. For example, Windows uses processes to isolate applications. This isolation is necessary to ensure that code running in one application cannot adversely affect other, unrelated applications.
Application domains provide an isolation boundary for security, reliability, and versioning, and for unloading assemblies. Application domains are typically created by runtime hosts, which are responsible for bootstrapping the common language runtime before an application is run.
http://msdn.microsoft.com/en-us/library/cxk374d9.aspx
AppDomains best visualized as a very light weight process.
There can be N AppDomains per .Net Process but generally speaking there is only one. The real advantage of AppDomains is they provide an isolation boundary within your process. Objects can only talk to each other across an AppDomain boundary via remoting or serialization.
It's also possible to run 2 AppDomains at completely different security levels within a process. This can allow you to run your main application at Full Trust while running Untrusted Plugins at a much lower trust level.
It's hard to blanket say yes or no to whether or not a thread respects an AppDomain. It's possible for a single thread to be in N different AppDomains. Such a situation is possible if an object in one AppDomain makes a remote call to an object in another AppDomain. The thread will have to transition between the AppDomains in order to complete.
The disadvantage of AppDomains is mainly complexity. Remoting can take a little bit of time to get your head around and properly setting up an AppDomain can be a non-trivial process.
You may want to take a peek through the MSDN documentation on AppDomains. It's hard to find a sucint tutorial that describes them because they have a variety of complex features. This provides a nice overview which if it doesn't answer your question directly will at least point you in the right place.
http://stackoverflow.com/questions/622516/i-dont-understand-application-domains by JaredPar

JaredPar's answer is good, except he doesn't note the raison d'etre for AppDomains - which is that you can only UNLOAD an Assembly by unloading its AppDomain. If you are a long-running OS process, and you expect to have to load and then later unload assemblies for whatever reason then you need an AppDomain. The prototypical example here is ASP.NET, which loads app code assemblies on demand and then can unload them later, when the apps are no longer being actively used.
The cost you pay for the ability to unload is that independence - you need to communicate across the AppDomain boundary, Can't make a simple method call. You need to manage the AppDomain lifecycle. Etc.
If you just need to dynamically load Assemblies and don't think you'll need to unload them during the life of a single process then you probably don't need to run multiple AppDomains. A good example here might be a rich app that supports a plug-in model, where it sniffs out plug-in assemblies in a "etc" directory and loads 'em all up. However, if the plug-in model calls for unloading the plug-ins ... well.
There are outlyer scenarios. Like, suppose you want to load 2 different versions of an Assembly at the same time. You can run into pitfalls if you don't segregate them with AppDomains. But that will be fairly rare.
The core scenario that justifies the existence of AppDomains is the long running process that must be able to unload assemblies.
Of course, applications could rely on the OS process when you want to unload an assembly. In other words, you could have 3 or 4 cooperating processes running, each with its own set of Assemblies, and when you want to unload an assembly, just shut down the process that hosts that assembly. But the AppDomain offers a higher-perf mechanism to do that, without requiring process stop/start or cross-process comms, which is heavier still than the cross-AppDomain comms described previously. I mean it's still remoting but it is slower and more context switching.
http://stackoverflow.com/questions/622516/i-dont-understand-application-domains by Cheeso

and now a solution how to run more appdomains in C#. ( http://blog.lab49.com/archives/2355 )

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Threading;
 
namespace WPFDomainLab
{
  class Startup
  {
    [STAThread()]
    static void Main()
    {
      var domain1 = AppDomain.CreateDomain(
        "first dedicated domain");
      var domain2 = AppDomain.CreateDomain(
        "second dedicated domain");
 
      CrossAppDomainDelegate action = () =>
      {
        Thread thread = new Thread(() =>
        {
          App app = new App();
          app.MainWindow = new Window1();
          app.MainWindow.Show();
          app.Run();
        });
        thread.SetApartmentState(
          ApartmentState.STA);
        thread.Start();
      };
 
      domain1.DoCallBack(action);
      domain2.DoCallBack(action);
    }
  }
}

please consider to use LoaderOptimization property... (here I would suggest to delete the app file and create your own, because the real main method is hided in the app.g.cs file by the visual studio).

For starting a wpf application it is neccessary to create a domain and then to call


1
newdomain.ExecuteAssembly(path); 

and in a finally block to call:

1
AppDomain.Unload(newdomain); 

What is quite cool in this solution is to be able to pass in some parameters. This communication works over:
 
1
newdomain.SetData(name, valueObject);


Kind regards,
Daniel

No comments: