Using Application Domains (C#)

Application domains, which are represented by AppDomain objects, help provide isolation, unloading, and security boundaries for executing managed code. You use application domains to isolate tasks that might bring down a process. If the state of the AppDomain that’s executing a task becomes unstable, the AppDomain can be unloaded without affecting the process. This is important when a process must run for long periods without restarting. You can also use application domains to isolate tasks that should not share data. If an assembly is loaded into the default application domain, it cannot be unloaded from memory while the process is running. However, if you open a second application domain to load and execute the assembly, the assembly is unloaded when that application domain is unloaded. Use this technique to minimize the working set of long-running processes that occasionally use large DLLs.
 
using System;
using System.Reflection;
using System.Threading;
 
class Module1
{
    public static void Main()
    {
        // Get and display the friendly name of the default AppDomain.
        string callingDomainName = Thread.GetDomain().FriendlyName;
        Console.WriteLine(callingDomainName);
        // Get and display the full name of the EXE assembly.
        string exeAssembly = Assembly.GetEntryAssembly().FullName;
        Console.WriteLine(exeAssembly);
        // Construct and initialize settings for a second AppDomain.
        AppDomainSetup ads = new AppDomainSetup();
        ads.ApplicationBase =
            System.Environment.CurrentDirectory;
        ads.DisallowBindingRedirects = false;
        ads.DisallowCodeDownload = true;
        ads.ConfigurationFile =
            AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
        // Create the second AppDomain.
        AppDomain ad2 = AppDomain.CreateDomain("AD #2", null, ads);
        // Create an instance of MarshalbyRefType in the second AppDomain.
        // A proxy to the object is returned.
        MarshalByRefType mbrt =
            (MarshalByRefType) ad2.CreateInstanceAndUnwrap(
                exeAssembly,
                typeof(MarshalByRefType).FullName
            );
        // Call a method on the object via the proxy, passing the
        // default AppDomain’s friendly name in as a parameter.
        mbrt.SomeMethod(callingDomainName);
        // Unload the second AppDomain. This deletes its object and
        // invalidates the proxy object.
        AppDomain.Unload(ad2);
        try
        {
            // Call the method again. Note that this time it fails
            // because the second AppDomain was unloaded.
            mbrt.SomeMethod(callingDomainName);
            Console.WriteLine("Sucessful call.");
        }
        catch(AppDomainUnloadedException)
        {
            Console.WriteLine("Failed call; this is expected.");
        }
    }
}
 
// Because this class is derived from MarshalByRefObject, a proxy
// to a MarshalByRefType object can be returned across an AppDomain
// boundary.
public class MarshalByRefType : MarshalByRefObject
{
    //  Call this method via a proxy.
    public void SomeMethod(string callingDomainName)
    {
        // Get this AppDomain’s settings and display some of them.
        AppDomainSetup ads = AppDomain.CurrentDomain.SetupInformation;
        Console.WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}",
            ads.ApplicationName,
            ads.ApplicationBase,
            ads.ConfigurationFile
        );
        // Display the name of the calling AppDomain and the name
        // of the second domain.
        // NOTE: The application’s thread has transitioned between
        // AppDomains.
        Console.WriteLine("Calling from ‘{0}’ to ‘{1}’.",
            callingDomainName,
            Thread.GetDomain().FriendlyName
        );
    }
}
 
/* This code produces output similar to the following:
AppDomainX.exe
AppDomainX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppName=, AppBase=C:\AppDomain\bin, ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config
Calling from ‘AppDomainX.exe’ to ‘AD #2’.
Failed call; this is expected.
 */
 
 

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

Calling Conventions (Cdecl, and StdCall) (C/C++)

What is Calling Conventions?
When a function is called, the arguments are typically passed to it, and the return value is retrieved. A calling convention describes how the arguments are passed and values returned by functions. It also specifies how the function names are decorated. Examples of calling conventions for functions are __cdecl and __stdcall.
 
What is Cdecl?
Older, unmanaged code that was developed by using the standard C libraries can implement functions that take variable numbers of parameters by using a technique that is known as varargs. Only the code that calls these functions knows for certain what it has placed on the stack, so it is the responsibility of the calling code to clean up the stack when the function completes. This is referred to as the Cdecl calling convention. It is the mechanism that unmanaged code that runs on Windows Embedded CE uses (you can use this as a point to select between Cdecl and StdCall nn your code).
 
What is StdCall?
Later implementations of the C libraries have removed the ability to provide variable numbers. In unmanaged code that uses these libraries, the responsibility for cleaning the stack lies with the called function, not the calling code. This is referred to as the StdCall
calling convention. It is the mechanism that unmanaged Win32 Windows API functions use (you can use this as a point to select between Cdecl and StdCall nn your code).
 
Example
Consider the following function (assuming we are using C):
 
int subtract(int a, int b)
{
    return a – b;
}
 
The call to this function will look like this:
 
int c = subtract(2, 3);
 
C calling convention (__cdecl)
We can declare a function to use the __cdecl convention like this:
 
int __cdecl subtract(int a, int b);
 
The main characteristics of __cdecl calling convention are:
1.Arguments are passed from right to left, and placed on the stack.
2.Stack cleanup is performed by the caller.
3.Function name is decorated by prefixing it with an underscore character ‘_’ .
 
 
Standard calling convention (__stdcall)
We can declare a function to use the __stdcall convention like this:
 
int __stdcall subtract(int a, int b);
 
The main characteristics of __stdcall calling convention are:
1.Arguments are passed from right to left, and placed on the stack.
2.Stack cleanup is performed by the called function.
3.Function name is decorated by prepending an underscore character and appending a ‘@’ character and the number of bytes of stack space required.
 

Writing XML with the XmlWriter Class (C#)

The XmlWriter class is an abstract base class that provides a forward-only, write-only, non-cached way of generating XML streams. It can be used to build XML documents that conform to the W3C Extensible Markup Language (XML) 1.0 (Second Edition) (www.w3.org/TR/2000/REC-xml-20001006.html) recommendation and the Namespaces in XML recommendation (www.w3.org/TR/REC-xml-names/). You can use the XmlWriter class to read and write XML.
 
The following example creates an XmlWriter that outputs to an XML file in C#.
 
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = ("    ");
using (XmlWriter writer = XmlWriter.Create("books.xml", settings))
{
    // Write XML data.
    writer.WriteStartElement("book");
    writer.WriteElementString("price", "19.95");
    writer.WriteEndElement();
    writer.Flush();
}