title: Isolate exceptions thrown in an AppDomain to not Crash the Application
body: <p>TL;DR: How do you isolate add-in exceptions from killing the main process?</p>
  
  <p>I want to have a very stable .Net application that runs less stable code in an <code>AppDomain</code>. This would appear to be one of the prime purposes of the <code>AppDomain</code> in the first place (well, that and security sandboxing) but it doesn't appear to work.</p>
  
  <p>For instance in <code>AddIn.exe</code>:</p>
  
  <pre><code>public static class Program
  {
      public static void Main(string[] args)
      {
          throw new Exception("test")
      }
  }
  </code></pre>
  
  <p>Called in my 'stable' code with:</p>
  
  <pre><code>var domain = AppDomain.CreateDomain("sandbox");
  domain.UnhandledException += (sender, e) =&gt; { 
      Console.WriteLine("\r\n ## Unhandled: " + ((Exception) e.ExceptionObject).Message);
  };
  domain.ExecuteAssemblyByName("AddIn.exe", "arg A", "arg B")
  </code></pre>
  
  <p>The exception thrown in the <code>AppDomain</code> gets passed straight to the application that created the domain. I can log these with <code>domain.UnhandledException</code> and catch them in the wrapper application.</p>
  
  <p>However, there are more problematic exceptions thrown, for instance:</p>
  
  <pre><code>public static class Program
  {
      public static void Main(string[] args)
      {
          Stackoverflow(1);
      }
  
      static int Stackoverflow(int x)
      {
          return Stackoverflow(++x);
      }
  }
  </code></pre>
  
  <p>This will throw a stackoverflow exception that kills the entire application every time. It doesn't even fire <code>domain.UnhandledException</code> - it just goes straight to killing the entire application.</p>
  
  <p>In addition calling things like <code>Environment.Exit()</code> from inside the <code>AppDomain</code> also kill the parent application, do not pass GO, do not collect £200 and don't run any <code>~Finialiser</code> or <code>Dispose()</code>.</p>
  
  <p>It seems from this that <code>AppDomain</code> fundamentally doesn't do what it claims (or at lease what it appears to claim) to do, as it just passes all exceptions straight to the parent domain, making it useless for isolation and pretty weak for any kind of security (if I can take out the parent process I can probably compromise the machine). That would be a pretty fundamental failure in .Net, so I must be missing something in my code.</p>
  
  <p>Am I missing something? Is there some way to make <code>AppDomain</code> actually isolate the code that it's running and unload when something bad happens? Am I using the wrong thing and is there some other .Net feature that does provide exception isolation?</p>