.NET Processes | Threads | Application Domains | Contexts & Their Relationships Exposed

I have been asked many times about the relationships between Processes, Application Domains (AppDomains) and Threads. Lets explore today various aspects of these objects along with their functionalities  in context to .NET framework.

Quality means doing it right when no one is looking.
Henry Ford

Quality providers are actually background workers and are invisible, always!  
Some Worker

Before going into the details, let me go through the Process in computing itself. A Process is actually an instance of an application that is loaded + executed in the memory by the OS (Operating System) on demand. Or in other terms when you run an application, the OS creates/loads it into a separate and isolated memory that is composed of at least three regions, Code Segment, Data Segments and Stack Segment and OS ensures of no overlapping among them, as well as also are protected from other processes (complete isolation). The code instructions are loaded in the code segment while all the global variables, objects, etc. are loaded in the data segment. This segment has also a space for heap, that used to be managed by the user in older days (C, C++ or un-managed applications) where as in recent OS’s like .NET it is managed by the garbage collector (GC) that is actually part of the .NET framework (more on it later) . Stack is used for local variables created in a function as well as return address of execution of the method/function. Code Segment is a read only/protected memory while Data Segment & Stack are read-write memory regions. In context to .NET, System.Diagnostics.Process abstracts away the Process details and provides handy utilities to get information about the Processes in the .NET driven applications. 

Now the obvious question is what is a Thread. Well I can only say “good question”, lets move on. Ok, Ok, If you really insist   A thread is merely a reusable path of execution per unit time slice of a processor or if its a multiprocessor that has exactly same processors as threads, then the execution is per processor. In a multithreading applications you could have more than one separate execution paths where some are managed by the application itself and some are spawned by the application developers as needed. When you run the application, the process creates a main/primary thread of execution that is actually an entry point for an application, like in WPF it is the Application.Run(.) or in console applications is the Main(.) method. As needed further threads are spawned by this primary thread also known as worker threads. That is why if you look at the framework, System.Threading.Thread is responsible for creating threads not the System.Diagnostics.Process.  All threads of a process share its virtual address space or they share a common heap memory (like the static and global variables are shared) . They are also provided with “Thread Local Storage (TLS)” [Wicki] and private call stack. Read more about these concepts here [msdn].

You may ask, why we use multithreading model instead of single threaded one? Well, because, the real world applications are distributed / multithreaded.   No one person can do each and every thing in this world/universe all alone. There is a team work involved for a big achievement. The work load has to be divided among specialized people / threads to get the ultimate job done. Like wise computer programs are no different. If you give a responsibility of every thing to the Primary thread then you’ll see that application will be sluggish, some times non-responsive that you might need to move on to a coffee thread . So for responsiveness, for quality work like long mathematical calculations / specialized real world needs you go for multithreaded / multiprocessor based applications.

Here is a minimal example of how we spawn a worker thread, i hope you don't like it . For more intuitive example, please take a look at my earlier post on blocking queues, here is the link for it. [Blocking Queues]

Code Snippet
  1. public class Test1
  2.     {
  3.         public static void RunCounter()
  4.         {
  5.             System.Diagnostics.Debug.WriteLine("Entering Main thread | " +
  6.                 Thread.CurrentThread.GetHashCode().ToString());
  7.  
  8.             // Create a worker thread
  9.             Thread workerThread = new Thread(delegate()
  10.             {
  11.                 System.Diagnostics.Debug.WriteLine("Entering workerThread, Hash is| " + Thread.CurrentThread.GetHashCode().ToString());
  12.  
  13.                 for (int i = 0; i < 11; i++)
  14.                 {
  15.                     System.Diagnostics.Debug.WriteLine(string.Format("Worker Thread counter: {0}", i));
  16.                     Thread.Sleep(500);
  17.                 }
  18.             });
  19.             workerThread.Start();
  20.  
  21.             // we are still in the main/primary thread
  22.             System.Diagnostics.Debug.WriteLine("Entering Again Main thread, Hash is | " +
  23.                 Thread.CurrentThread.GetHashCode().ToString());
  24.  
  25.             for (int i = 0; i < 7; i++)
  26.             {
  27.                 System.Diagnostics.Debug.WriteLine(string.Format("Main thread counter : {0}", i));
  28.                 
  29.                 Thread.Sleep(1000);
  30.             }
  31.  
  32.             System.Diagnostics.Debug.WriteLine("--- Main thread, work done ---");
  33.         }
  34.  
  35.         /* Output :>
  36.             Entering Main thread | 10
  37.             Entering Again Main thread, Hash is | 10
  38.             Entering workerThread, Hash is| 3
  39.             Worker Thread counter: 0
  40.             Main thread counter : 0
  41.             Worker Thread counter: 1
  42.             Worker Thread counter: 2
  43.             Main thread counter : 1
  44.             Worker Thread counter: 3
  45.             Worker Thread counter: 4
  46.             Main thread counter : 2
  47.             Worker Thread counter: 5
  48.             Worker Thread counter: 6
  49.             Main thread counter : 3
  50.             Worker Thread counter: 7
  51.             Worker Thread counter: 8
  52.             Main thread counter : 4
  53.             Worker Thread counter: 9
  54.             Worker Thread counter: 10
  55.             Main thread counter : 5
  56.             The thread '<No Name>' (0x2bfc) has exited with code 0 (0x0).
  57.             Main thread counter : 6
  58.             --- Main thread, work done ---
  59.          * */
  60.     }

 

Now lets move on to .NET Application Domains or simply AppDomains. AppDomains are actually a subdivision or logical partition within Process in order to host .NET executables/assemblies. A process can have or can host one or more AppDomains as shown in the figure below (Figure-1). And an AppDomain can have one (+1) or more (+*) Contexts or Context Boundaries (I’ll come to this a little later).

Process Figure-1

ClassDiagram02 Figure-2

So now the question is why we need AppDomains. As you know when you run a .NET application it is managed by a OS/platform independent runtime known as Common Language Runtime (CLR). and the CLR gets this independency with the help of AppDomains and the class that is responsible for this job is System.AppDomain (Figure-2 above). AppDomains are like a light-weight process in terms of memory and processing requirements and they can be unloaded or loaded on-demand by the process or by the developer as needed.  Like the primary thread was created by the Process, the CLR automatically creates a default or primary AppDomain and hosts your application right away. Further AppDomains can be created by calling AppDomain.CreateDomain(.) static factory method. If you have more than one AppDomain, these AppDomains are isolated from each other and when they need to send information among each other, the information (like heap data) needs to be marshaled and that’s why it is derived from MarshalByRefObject or in simple terms the AppDomains are remotable objects (Look for C# Remoting for MarshalByRefObject).  The interesting methods in the AppDomain class are encircled above (Figure-2).

ClassDiagram03 Figure-3

Last but not least the “Contexts”; As mentioned earlier A process is composed/subdivided into 1-n AppDomains likewise AppDomains are composed of one to many Contexts or Context Boundaries. The context provides a special purpose boundary around an object, if adorned with a ContextAttribute. Like, if you look at the Figure-3, SynchronizationAttribute, if adorned on an object, the whole object will become thread-safe.  Also, like default AppDomain, the AppDomain creates a default context known as “context-0”. It is the first context where the objects resides who don't have special needs and these regular objects, loaded in some application domain, are also known as Context-Agile objects. Here is an example of a special need object, that needs synchronization or inherent thread-safety provided by CLR running for WPF applications.

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. using System.Runtime.Remoting.Contexts;
  7. using System.Threading;
  8.  
  9. namespace WpfTestApp
  10. {
  11.     // SynchronizationAttribute Enforces a synchronization domain for the
  12.     // current context and all contexts that share the same instance.
  13.     // Any object loaded in this context is thread-safe.
  14.     //
  15.     [Synchronization]
  16.     class SyncContextBoundObject : ContextBoundObject
  17.     {
  18.         public SyncContextBoundObject() {}
  19.  
  20.         public void ShowContextInfo()
  21.         {
  22.             // Display Current AppDomain Info
  23.             System.Diagnostics.Debug.WriteLine("AppDomain Id | " + AppDomain.CurrentDomain.Id.ToString());
  24.             System.Diagnostics.Debug.WriteLine("AppDomain FriendlyName | " + AppDomain.CurrentDomain.FriendlyName);
  25.             
  26.             // Display Current Thread Info
  27.             System.Diagnostics.Debug.WriteLine("Thread FriendlyName | " + Thread.CurrentThread.Name);
  28.             System.Diagnostics.Debug.WriteLine("Thread HashCode | " + Thread.CurrentThread.GetHashCode().ToString());
  29.  
  30.             // Display Current Context Info
  31.             System.Diagnostics.Debug.WriteLine("Context ID | " + Thread.CurrentContext.ContextID);
  32.             System.Diagnostics.Debug.WriteLine("Thread HashCode | " + Thread.CurrentContext.GetHashCode().ToString());
  33.  
  34.             // Display Context Properties...
  35.             foreach (IContextProperty contextProperty in Thread.CurrentContext.ContextProperties)
  36.             {
  37.                 System.Diagnostics.Debug.WriteLine("Context Property[.] | " + contextProperty.Name);
  38.             }
  39.             
  40.         }
  41.  
  42.         public void ShowPrimesUsingLinq(int n)
  43.         {
  44.             Func<int, IEnumerable<int>> primeNumbersExpr = (x) =>
  45.                  from i in Enumerable.Range(2, x - 1)
  46.                     where Enumerable.Range(2, i - 2).All(j => i % j != 0)
  47.                         select i;
  48.  
  49.             var resultSet = primeNumbersExpr(n);
  50.  
  51.             foreach (int i in resultSet)
  52.             {
  53.                 System.Diagnostics.Debug.WriteLine(i);
  54.             }
  55.         }
  56.     }
  57.  
  58.     public class Test2
  59.     {
  60.         public static void RunSyncContext()
  61.         {
  62.             SyncContextBoundObject syncObject = new SyncContextBoundObject();
  63.             syncObject.ShowContextInfo();
  64.             /* Output :>            
  65.                     AppDomain Id | 1
  66.                     AppDomain FriendlyName | WpfTestApp.vshost.exe
  67.                     Thread FriendlyName |
  68.                     Thread HashCode | 10
  69.                     Context ID | 1
  70.                     Context Property[.] | LeaseLifeTimeServiceProperty
  71.                     Context Property[.] | Synchronization
  72.             */
  73.             syncObject.ShowPrimesUsingLinq(11);
  74.         }
  75.     }
  76. }

One more thing that is important and quite notable is that although, their is no direct coherence between AppDomains and Threads (Figure-1) but a particular thread when activated is attached to One particular AppDomain. Or in other words, like AppDomains, the threads are not restricted to one domain, rather they are free to move around in different AppDomains, the only restriction is, a thread cannot be present in two different locations/domains at one time.

That's all for now folks, will talk to you more on threading next time. I’ll be looking forward to your feedbacks/comments, enjoy

 

If you enjoyed reading this blog, leave your valuable feedback and consider subscribing to the RSS feed. You can also subscribe to it by email. Also, you can follow me on Twitter. Thank you!

 

Comments (7) -

increase net income
2/23/2016 7:35:15 AM #

Keep on working, great job!  Feel free to visit my blog  increase net income - fullerqmxnniliik.webgarden.com/.../learn-the-smart-technique-to

We stumbled over here by a different web address and thought I might check things out. I like what I see so i am just following you. Look forward to looking over your web page repeatedly.

recycling resource
2/29/2016 10:57:50 AM #

It's a shame you don't have a donate button! I'd definitely donate to this excellent blog! I guess for now i'll settle for bookmarking and adding your RSS feed to my Google account. I look forward to brand new updates and will share this blog with my Facebook group. Talk soon!

Jared
2/29/2016 2:28:11 PM #

Some sort of treadmill is excellent intended for walking, running, plus also jogging.  My blog ...  Jared - www.blackplanet.com/.../view_posting.html

self inspiration
3/2/2016 8:21:37 PM #

Hi would you mind letting me know which webhost you're using? I've loaded your blog in 3 completely different browsers and I must say this blog loads a lot faster then most. Can you recommend a good internet hosting provider at a reasonable price? Many thanks, I appreciate it!

porno
3/5/2016 1:52:47 AM #

Hi to all, how is the whole thing, I think every one is getting more from this site, and your views are nice designed for new people.

program software downloads
3/11/2016 8:14:09 PM #

This is actually the best number of sites where their favorite application can be found by net geeks for free download.  program software downloads - http://dzhoppa111.com  that is free download, the biggest application directory for freeware and shareware download below.

porno
3/12/2016 8:21:33 AM #

I am sure this post has touched all the internet visitors, its really really nice paragraph on building up new web site.

vuelos baratos a buzios
3/13/2016 3:11:48 AM #

Hi there to every one, it's actually a fastidious for me to pay a visit this web site, it consists of useful Information.

https://Www.kompany.co.uk
3/14/2016 12:59:34 PM #

Unfortunately, it turns out that Coach O'Leary wasn't as decorated and degreed as he had claimed. Doing a rental background check serves as your primary protection against your property destruction, non-paying tenants, and abusive and criminal tenants. An online registration facility gives you the option of securing the registration with a payment.

Contractor umbrella companies uk
3/25/2016 12:50:31 AM #

Hello friends, how is everything, and what you would like to say on the topic of this piece of writing, in my view its in fact remarkable for me.  My web-site:  Contractor umbrella companies uk - www.4a-friend.com/.../index.php

www.porntsar.com
3/31/2016 9:51:47 PM #

Wonderful blog! I found it while browsing on Yahoo News. Do you have any suggestions on how to get listed in Yahoo News? I've been trying for a while but I never seem to get there! Many thanks

venus Factor Workout Free download
4/8/2016 10:21:01 PM #

This assists spend for our net hosting, and so on.  Here is my weblog:  venus Factor Workout Free download - http://s3.amazonaws.com/loswgt/index/133.html

Umbrella Company
4/11/2016 5:54:41 PM #

magnificent points altogether, you just gained a new reader. What could you suggest in regards to your put up that you just made some days in the past? Any sure?  Look at my web blog ::  Umbrella Company - http://durl.me/bxreci

umbrella companies for contractors
4/12/2016 7:06:40 AM #

Wow, amazing blog structure! How lengthy have you ever been blogging for? you make running a blog glance easy. The overall glance of your web site is wonderful, let alone the content material!  Feel free to visit my weblog -  umbrella companies for contractors - Www.Libertypropertytrust.com/.../...ltrademark.php

geekscafe.net
4/27/2016 5:52:59 AM #

Hi to every single one, it's really a fastidious for me to pay a quick visit this web site, it contains precious Information.

fiverr google login
5/5/2016 6:03:16 AM #

Many of their ‘gigs' - that's what Fiverr choices are called - are kinda sleazy.  my page ::  fiverr google login - www.rebelmouse.com/.../...he-cheap-1775194903.html

Lån 10000
5/26/2016 5:14:00 PM #

• renteudsving risiko.

Add comment