.NET Framework Developer Center > .NET Development Forums > Common Language Runtime > How to accomplish fault isolation with AppDomain?
Ask a questionAsk a question
 

AnswerHow to accomplish fault isolation with AppDomain?

  • Tuesday, January 09, 2007 3:01 PMClinton Chau Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi all,

    I have read several articles on the net, and also Juval Lowy's "Programming .NET Components (2nd ed.)" and these references imply that it is possible to achieve fault isolation to the same degree that you traditionally got from using multi-process programs, using AppDomains.

    At the same time, I have read other articles, in particular those describing the Application Pool architecture of ASP.NET which leads me to believe that in order to achieve true fault isolation, you still need to use multiple processes. My own experiments seem to lead to the same conclusion.

    What is the right answer? Could someone on this forum offer pointers to some good references or some additional insight?

    To be complete, here's an outline of my experiment: I want to construct a program that will act as a 'host' program for other subprograms that will run like services. The host will scan a folder for assemblies that conform to certain attributes. The "scanning" takes place in a secondary AppDomain which I call "StagingDomain". It will then return a list of assemblies that match via Remoting, back to the default AppDomain. From here, it will create new AppDomains for each subprogram that was found, load the assemblies and create instances in the new AppDomains, returning a reference to the instance in the new AppDoimain. Finally, it will create a thread, which will call the Start() method of the instance of the subprogram.

    Example: The scanning in StagingDomain finds three subprograms, CalculatePi, CalculatePrime, and WillCrash. In the default AppDomain and from the main thread, I will create three new AppDomains called "CalculatePi", "CalculatePrime" and "WillCrash", and then use CreateInstanceFromAndUnwrap() to create instances of the subprograms in their respective AppDomains. I will then spawn a new thread, one for each subprogram, and call the Start() routine for each.

    Logging indicates that each subprogram correctly runs from within their own AppDomain. WillCrash will purposely throw a System.ApplicationException that is unhandled after 2 minutes.

    The result is that the entire shebang collapses. The host program stops as well as all the threads in the other AppDomains.

    Any light at all as to what I'm doing wrong will be much appreciated.

    Thanks in advance,

    Clinton Chau

Answers

  • Wednesday, January 10, 2007 12:13 AMAlois Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Hi Chau,

    to answer you question the short way: No you cannot use AppDomains this way. But you can use AppDomains to support dynamic re/loading of plugins like independent ASP.NET pages which have no interdependencies. This is the main feature of AppDomains to support unloading of plugins at run time with all data contained inside it in a more or less clean way.

    If you trigger abort/exit inside C(++) the C-Runtime will trigger a call to the CLR before the process is shut down. Your C/++ code does not become more stable in any way when the CLR is running inside the process. Unmanaged code has nothing to do with AppDomains and does not know that it was called from one or the other AppDomain.

    Yours,
        Alois Kraus

All Replies

  • Tuesday, January 09, 2007 4:39 PMAlois Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi Chau,

    this http://geekswithblogs.net/akraus1/archive/2006/10/30/95435.aspx article shows you when your application will terminate.

    The relevant section for you is this handler:

    AppDomain.UnhandledException is called only in the default AppDomain. You can register this handler only in the "root" AppDomain which is the first one created for you by the CLR. Hosting of other AppDomains in a plugin architecture can cause unexpected side effects if the loaded modules register this handler and expect it to be called. When the handler is left the process finally terminates which cannot be prevented in .NET 2.0 except if you set a compatibility flag inside the runtime settings your App.config file.

    <legacyUnhandledExceptionPolicy enabled="1"/>

    The UnhandledException handler is called in your "root" application domain which will cause the whole process to terminate. When a thread dies the whole process will terminate regardless in what appdomain it crashed. You can host the CLR by yourself and change the default behaviour to enable you to unload the faulting AppDomain or set this compatibility flag which will lead to much harder to find errors in the long run. Since your AppDomains run inside the same process they can overwrite memory without problems (when doing much with unmanaged code) which will corrupt your process anyway. The CLR Threadpool is shared across AppDomains which will stop working if e.g. one AppDomain blocks all threads in the thread pool for some reason, even if you do unload the faulting AppDomain the threadpool threads will remain blocked.

    Yours,

      Alois Kraus

  • Tuesday, January 09, 2007 6:41 PMClinton Chau Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi Alois,

    From your response, your stance is that AppDomains cannot be used for fault-isolation, is that correct? (That was my original question.)

    Thanks for the pointer to your article and the additional information regarding the legacyUnhandledExceptionPolicy flag. By way of the use of the AppDomain.UnhandledException event, there is another article where in the comments, Jonathan Keljo, CLR Exceptions PM talks about this subject (http://www.codinghorror.com/blog/archives/000201.html).

    Any other takers on this subject? IF AppDomains can be used for fault-isolation, my followup question would be, what happens if the assembly in one of the AppDomain runs unmanaged code that creates an abort() condition?

    Thanks,

    Clinton Chau

  • Wednesday, January 10, 2007 12:13 AMAlois Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Hi Chau,

    to answer you question the short way: No you cannot use AppDomains this way. But you can use AppDomains to support dynamic re/loading of plugins like independent ASP.NET pages which have no interdependencies. This is the main feature of AppDomains to support unloading of plugins at run time with all data contained inside it in a more or less clean way.

    If you trigger abort/exit inside C(++) the C-Runtime will trigger a call to the CLR before the process is shut down. Your C/++ code does not become more stable in any way when the CLR is running inside the process. Unmanaged code has nothing to do with AppDomains and does not know that it was called from one or the other AppDomain.

    Yours,
        Alois Kraus

  • Wednesday, January 10, 2007 3:40 PMClinton Chau Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi Alois,

    Thanks for the followup. I think you have answered my question, although I'll leave the thread open for a few more days just to see if there are other opinions, if you don't mind. I suppose I should interpret people's claims of 'fault isolation' using AppDomains, to mean the isolation of memory faults, as long as all the code that is running in the CLR is managed code, since unmanaged code cannot be checked.

    My question about the C abort() was made only to emphasize the point that you cannot use AppDomains to isolate incidences of faults and crashes, in the same way that you could with multi-process programs, in order to increase the stability of the server program (see my original question).

    Clinton Chau