Mark Michaelis' Weblog :
Updated: 9/1/2004; 6:57:48 AM.

 








Subscribe to "Mark Michaelis' Weblog" in Radio UserLand.

Click to see the XML version of this web page.

Click here to send an email to the editor of this weblog.

Subscribe To
Mark's Weblog

 
 

Monday, April 07, 2003

Gracefully Handling Unhandled Exceptions
Google Search It

To gracefully handle unhandled exceptions within your AppDomain you need to set the AppDomain.UnhandledException event to a delegate of type  UnhandledExceptionEventHandler as follows:

 AppDomain.CurrentDomain.UnhandledException +=
    new UnhandledExceptionEventHandler(RemotingHostAppDomain_UnhandledException);

Where the UnhandledExceptionEventHandler delegate looks like this:

public static void RemotingHostAppDomain_UnhandledException(
   object sender, UnhandledExceptionEventArgs args)
{
    System.Diagnostics.Trace.WriteLine(
       "ERROR: {0}", args.ExceptionObject.ToString());
}


3:40:58 AM   []    comment []

Unable to Consistently Unload an AppDomain
Google Search It

I have been doing testing of remoting using AppDomains but I have unfortunately run across a snag when unloading those AppDomains.  An attempt to unload an AppDomain consistently seems to throw an exception the second time I initialize and then unload the app domain.  The error message is, "AppDomain can not be unloaded because the thread 954 can not be unwound out of it."  (Obviously with the thread id varying for each run.)

I initialize the AppDomain using the following code:

public void InitializeRemotingHostAppDomain()
{
    AppDomainSetup setup =
new AppDomainSetup();
    setup.ApplicationBase = CodeBase.Path();
    Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
    Evidence evidence =
new Evidence(baseEvidence);

    RemotingHostAppDomain = AppDomain.CreateDomain(
        "Client Domain", evidence, setup);
    RemotingHostAppDomain.InitializeLifetimeService(;
}

... and the unload code looks like this:

public void UnInitializeRemotingHostAppDomain()
{
   // Unload Appdomain
   if(RemotingHostAppDomain != null)
   {
      AppDomain.Unload(RemotingHostAppDomain);
      RemotingHostAppDomain=null;
   }
}

From what I can tell there is no Dispose() method on AppDomain that I have neglected to call or anything.  And yet, I suspect that this is a garbage-collector-not-yet-run type of issue.  The reason I suspect this is if I wait long enoug between repeated exections of the above code then everything seems to work.

To work around the issue generically I tried to catch the exception and retry the unload until it worked:

public void UnInitializeRemotingHostAppDomain()
  {
     CannotUnloadAppDomainException cannotUnloadException = null;
     int count=0;

     // Unload Appdomain
     if(RemotingHostAppDomain != null)
     {
        do
        {
             cannotUnloadException = null;
             try
             {
                  AppDomain.Unload(RemotingHostAppDomain);
             }
             catch(CannotUnloadAppDomainException exception)
             {
                 cannotUnloadException = exception;
                 count++;
             }
         }
         while(cannotUnloadException != null);

         RemotingHostAppDomain=null;
         System.Diagnostics.Trace.WriteLineIf((count!=0),
             string.Format("THE COUNT IS: {0}", count));
     }
}

Although this seemed to improve the reliability significantly it still wasn't 100% reliable.  Furthermore, although the reliability was improved, often the trace message didn't appear in the debug window indicating that, in fact, an exception had been thrown. 

One of the problems with AppDomain.UnLoad() is that it often generates a ThreadAbortException as follows:

An unhandled exception of type 'System.Threading.ThreadAbortException' occurred in Unknown Module.

It is not clear to me at the moment how this can be avoided.  For the moment, this issues surrounding AppDomain.UnLoad() remain unresolved.


2:53:47 AM   []    comment []

While investigating some remoting stuff I came across the System.AppDomain.ExecuteAssembly( ) method.  This was interesting to me because if shows a way to launch a new app domain that hosts an executable without actually starting a new operating system/win32 process.  The console application that I tested with created a Application within the Application List of Windows Task Manager but if one looked at the list of processes in the Windows Task Manager it didn't show up, presumably proving that no new win32 process was created when using the ExecuteAssembly( ) method.

Here is some of the sample code I used to test the method (as usual I tested using NUnit).

using System;
using System.Security.Policy;
using NUnit.Framework;

namespace
RemotingSamples.Test
{
    [TestFixture]
    public class AppDomainTest
    {
        [Test]
        public void ExecuteAssembly()
        {
            AppDomain appDomain;
            AppDomainSetup setup =
new AppDomainSetup();
            setup.ApplicationBase = CodeBase.Path();
            Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
            Evidence evidence =
new Evidence(baseEvidence);

            appDomain = AppDomain.CreateDomain(
                "Client Domain", evidence, setup);
            appDomain.InitializeLifetimeService();
            appDomain.ExecuteAssembly(@"ConsoleTest.exe");
        }
    }
}

12:47:33 AM   []    comment []

Benjamin Getting a Mug Shot for Lost Kids Program
Google Search It

Normally a very happy child Benjamin simply refused to smile when getting his picture taken during a lost kids prevention/registration program at the local YMCA.  As Elisabeth said, however, perhaps this shot is more accurate as it will reflect his dejected state if something were to happen.

Benjamin Getting a Mug Shot for Lost Kids Program


12:06:35 AM   []    comment []

© Copyright 2004 Mark Michaelis.



 


April 2003
Sun Mon Tue Wed Thu Fri Sat
    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      
Mar   May


Recent Posts