C# · Dotnet

Get AppDomains in a process

Dear Reader,

Today i got a bit curious about AppDomains concept so i began to go indepth to learn about it. As we know AppDomains do play a vital role in the application developement. These .net feature do comes in handy in various situations. One such situation i would like to share with you from my previous project.

We had to monitor multiple ports parallely in a industrial PC via our software for some inputs, based on which we had to do some other processing. As you might think off, we could have done this via creating multple threads. But the constraints we had is to have the latency of just 5 ms difference in getting values. Our POC on thread showed that (.net 3.5, so no TPL), some times the latency in getting values from some ports (max 6 ports) when loaded full was taking more than 1 sec to get the values. The problem was that some times some threads do not get time slice to get processed.

For our next POC, we chose to use AppDomains in a single process. Thus we created 6 AppDomains to monitor 6 ports and 1 default AppDomain which .NET application process creates. At first this might sounds like not light weight than a thread, because AppDomain creates more memory and has more stuffs which it creates than a thread. So what we did was to create as light as possible operations in each of these appdomains from the application point of view.

So we carefully developed an assembly which just reads the port and gives to other process running parallely which will take care of further processing such as saving to DB/File. We had to optimize this assembly code as much as possible to improve its performance. So this POC proved in most cases to be much reliable than with just threads in terms of getting accurate values every time slice as we wanted.
Other usage of this AppDomains is thats its very easy to unload the whole assembly if there is a crash/exception and re-create/load it back on as if nothing has happened which can not be done with threads, because If one of the threads throws an exception and if its not handled then whole application crashes.

Recently i had a argument with a colleague about the default AppDomains which gets created when you launch a .net application. I was arguing that it would create only 1 appdomain which is default, where as he stated that it would create 3 appdomains. I also searched CLR via C# if there is such thing going on in .net, alas could not find it. I think he got confused from the native appdomains with the .net world.

So today i was just rethinking about the same argument and wanted to dig more and see if i can get all the currently running appdomains from the process to test his argument. So i looked for how to do that. So below is the code i learned on how to do it. So i started to play with the code for a bit.

Below code is for .NET 4 version.

using System;
using mscoree;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        static object o = new object();

        static void Main(string[] args)
        {
            AppDomain appDom = AppDomain.CreateDomain("Domain1");
            AppDomain appDom1 = AppDomain.CreateDomain("Domain2");

            GetAppDomains();

            AppDomain.Unload(appDom);
            GetAppDomains();
            Console.ReadLine();

        }

        public static void GetAppDomains()
        {
            IntPtr enumHandle = IntPtr.Zero;
            ICorRuntimeHost host = new mscoree.CorRuntimeHost();
            try
            {
                host.EnumDomains(out enumHandle);
                object domain = null;

                while (true)
                {
                    host.NextDomain(enumHandle, out domain);
                    if (domain == null) break;
                    Console.WriteLine(((AppDomain)domain).FriendlyName);
                    Console.WriteLine(((AppDomain)domain).IsDefaultAppDomain());
                    Console.WriteLine();
                } 
            }
            catch (Exception e) { Console.WriteLine(e.ToString()); return; }
            finally
            {
                host.CloseEnum(enumHandle); Marshal.ReleaseComObject(host);
            }
        }
    }
}

For the above code to work, you have to add a static COM reference of C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\mscoree.tlb via Project -> Add References window.

This code lists out all the AppDomains created inside the process. This can help us to control AppDomanins in what ever way we require at a later point of time with out needing to the hold the same reference of original Appdomain object.

Hope it helps.

Thanks & Happy coding,

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

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