AppDomain (C#)

Usually each process runs in its own space and if first process making a call to second process, and if second process crashes, so first will also crash. In .NET, we attempt to solve this problem through Application Domains. An Application Domain is a virtual location in memory where a process runs. The main process is created by the .NET CLR and then, each assembly runs in its own Application Domain. And many Application Domains can exist in a single process space. So, if one Application Domain crashes, only its space is released and the process remains as is.

If an Application Domain does crash, the CLR throws back an exception which can be handled in the caller. The AppDomain class is the programmatic interface to application domains. This class includes methods to create and unload domains, to create instances of types in domains, and to register for various notifications such as application domain unloading.

Let’s start with a simple example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace AppDomain1
{
    class Program
    {
        static void Main(string[] args)
        {
            Worker localWorker = new Worker();
            Console.WriteLine("localWorker is running in: {0}", localWorker.DomainName);
            AppDomain myDomain = null;
            try
            {
                myDomain = AppDomain.CreateDomain("Remote Domain");
                Worker remoteWorker = (Worker)myDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "MyAppDomain.Worker");
                Console.WriteLine("remoteWorker is running in: {0}", remoteWorker.DomainName);
            }
            finally
            {
                if (myDomain != null)
                    AppDomain.Unload(myDomain);
            }
        }
    }
 
    public class Worker : MarshalByRefObject
    {
        public Worker()
        {
        }

        public string DomainName
        {
            get
            {
                return AppDomain.CurrentDomain.FriendlyName;
            }
        }
    }
}

Now, let’s try to crash… Unhandled exceptions can cause code to crash or leave your application in an unstable state. Application Domains are isolated and can help you to catch unhandled exceptions and unload the application domain when needed. So when we expand our example to include this, we get something like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace AppDomain2
{
    class Program
    {
        static void Main(string[] args)
        {
            AppDomain myDomain = null;
            try
            {
                myDomain = AppDomain.CreateDomain("Remote Domain");
                myDomain.UnhandledException += new UnhandledExceptionEventHandler(myDomain_UnhandledException);
                Worker remoteWorker = (Worker)myDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Worker).FullName);
                remoteWorker.VeryBadMethod();
            }
            catch(Exception ex)
            {
                myDomain_UnhandledException(myDomain, new UnhandledExceptionEventArgs(ex, false));
            }
            finally
            {
                if (myDomain != null)
                    AppDomain.Unload(myDomain);
            }
 
            Console.ReadLine();
        }
 
        static void myDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception ex = e.ExceptionObject as Exception;
            if (ex != null)
                Console.WriteLine(ex.Message);
            else
                Console.WriteLine("A unknown exception was thrown");
        }
    }
 
    public class Worker : MarshalByRefObject
    {
        public Worker()
        {
        }
 
        public string DomainName
        {
            get
            {
                return AppDomain.CurrentDomain.FriendlyName;
            }
        }
 
        public void VeryBadMethod()
        {
            // Outch!
            throw new InvalidOperationException();
        }
    }
}

Full Source Code Download: http://cid-d1df34a904545dc5.skydrive.live.com/self.aspx/Public/AppDomain.zip

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: