C# AppDomain

C# AppDomain: .NET Platform में Executables Directly Windows Process में Hosted नहीं होते, जैसाकि अन्‍य Windows Based Unmanaged Applications में होते हैं। बल्कि .NET Executables किसी Process के एक Logical Partition में Hosted होता है, जिसे Application Domain के नाम से जाना जाता है।

अत: एक Single Process में Multiple Application Hosted हो सकते हैं क्योंकि एक Process में कई Application Domains हो सकते हैं। Windows Process के इस Subdivision के कारण हमें कई Extra Benefits प्राप्त होते हैं, जिनमें से कुछ निम्नानुसार हैं:

  • AppDomains की वजह से हमारा .NET Application Operating System Neutral हो जाता है।
  • AppDomains कम Resources Use करते हैं, जिसकी वजह से .NET Applications ज्यादा तेजी से Load व Unload हो सकते हैं।
  • AppDomains की वजह से Application व Operating System के बीच कम Functional Dependency होती है।

जैसाकि हमने पहले कहा कि एक Process में कई AppDomains हो सकते हैं इसलिए एक Process के सभी AppDomains एक दूसरे से पूरी तरह से Isolated होते हैं। परिणामस्वरूप एक AppDomain में Run हो रहा Application किसी दूसरे AppDomain के Data को किसी भी स्थिति में Directly Access नहीं कर सकताए जब तक कि हम स्वयं कोई Global Programming Protocol जैसे कि Windows Communication Foundation Use न करें।

साथ ही कोई Operating System Process स्वयं एक ऐसे AppDomain को Host करता है, जिसे Default Application Domain के नाम से जाना जाता है। ये Specific Application Domain उस समय Automatically CLR द्वारा Create किया जाता है, जब Process Launch होता है।

इस Default Application Domain के Create होने के बाद ही जरूरत के आधार पर CLR अन्‍य Additional Application Domains को Create करता है।

C# AppDomain – System.AppDomain Class

.NET Platform हमें किसी Process के विभिन्न AppDomains को Programmatically Monitor करने के लिए System.AppDomain नाम की Class Provide करता है, जिसका प्रयोग करके हम Runtime में किसी Process में किसी AppDomain को Create कर सकते हैं, AppDomains में किसी Assembly को Load कर सकते हैं और विभिन्न प्रकार के अन्‍य Tasks को Perform कर सकते हैं।

System.AppDomain Class एक BCL Class है, जिसे mscorlib.dll Assembly में System Namespace के अन्तर्गत Define किया गया है। इस Class में निम्न Methods को Define किया गया है, जिन्हें किसी Process के AppDomains को Handle करने हेतु उपयोग में लिया जा सकता है:

CreateDomain() Method

ये Static Method हमें Current Process में नया AppDomain Create करने की सुविधा Provide करता है।

CreateInstance() Method

Specified Assembly को Current Application Domain में Load करने के बाद ये Method उस Specified External Assembly में किसी Specific Type का Instance Create करता है।

ExecuteAssembly() Method

ये Method किसी Specified Filename की *.exe Assembly को किसी Application Domain में Execute करता है।

GetAssembly() Method

ये Method उन सभी .NET Assemblies को Retrieve करता है, जो Current Application Domain में Load हुई हैं। ये Method COM-Based व C-Based Binaries को Ignore कर देता है।

Load() Method

ये Method किसी Specified Assembly को Current Application Domain में Dynamically Load करता है।

Unload() Method

ये Static Method किसी Specified Process से किसी Specified AppDomain को Unload करता है।

इन Methods के अलावा AppDomain Class हमें कुछ Properties भी Provide करता है, जिनका प्रयोग किसी Specified Application Domain को Monitor करने के लिए किया जा सकता है। इनमें से कुछ मुख्‍य रूप से उपयोगी Properties निम्नानुसार हैं:

BaseDirectory Property

ये Property उस Assembly के Directory Path को Represent करता है, जिसे Assembly Resolver Assembly को Search करने के लिए Use करता है।

CurrentDomain Property

ये Static Property, Currently Executing Thread के Application Domain को Return करता है।

FriendlyName Property

ये Property Current Application का Friendly Name Return करता है।

MonitoringIsEnabled Property

ये Property एक Value द्वारा Get या Set होता है, जो इस बात को Indicate करता है कि Current Process के Application Domains के लिए CPU व Memory Monitoring Enabled है या नहीं। जब एक बार किसी Process के लिए Monitoring को Enable कर दिया जाता है, उसके बाद उसे Disable नहीं किया जा सकता।

SetupInformation Property

ये Property किसी Specified Application Domain के लिए Specified Configuration Details को Return करता है, जिसे AppDomainsSetup Object द्वारा Represent किया जाता है।

इनके अलावा AppDomain Class कुछ Events को भी Support करता है, जो कि किसी Application Domain की Life Cycle के विभिन्न Aspects से सम्बंधित होते हैं। इन Events को निम्नानुसार समझा जा सकता है:

AssemblyLoad Event

ये Event तब Trigger होता है जब Assembly Memory में Load हो जाता है।

AssemblyResolve Event

ये Event तब Trigger होता है जब Assembly Resolver किसी Required Assembly की Location प्राप्त नहीं कर पाता।

DomainUnload Event

ये Event तब Trigger होता है जब AppDomain Hosting Process से Unload होने ही वाला होता है।

FirstChanceException Event

ये Event हमें उस समय Notification प्राप्त करने की सुविधा देता है, जब Application Domain से कोई Exception Throw होता है, लेकिन CLR उस Exception के लिए Appropriate Catch Statement के लिए Searching कर रहा होता है।

ProcessExit  Event

ये Event तब Default Application Domain के लिए तब Trigger होता है जब Default Application Domain का Parent Process Exit होता है।

UnhandledException  Event

ये Event तब Trigger होता है जब किसी Exception को कोई Exception Handler Catch नहीं कर पाता।

Using System.AppDomain

जब .NET Executable Start होता है, तो CLR Automatically उसे Hosting Process के अन्दर एक Default AppDomain में Place कर देता है। ये काम Automatically और Transparently होता है और इसके लिए हमें कोई Code लिखने की जरूरत नहीं होती।

लेकिन यदि हम चाहें तो इस Default Application Domain को AppDomain.CurrentDomain Property द्वारा Access कर सकते हैं और इस Property के माध्‍यम से एक बार Default Application Domain का Access Point प्राप्त हो जाने के बाद तब हम हमारी जरूरत के अनुसार इस Access Point के साथ विभिन्न प्रकार के Events को Hook कर सकते हैं अथवा AppDomain की विभिन्न Properties व Methods को Use करके Runtime Diagnostics कर सकते हैं। जैसे:

File Name: AppDomain.cs
using System;
using System.Linq;
using System.Diagnostics;
using System.Reflection;

namespace CSharpMultiThreading
{
    class ApplicationDomain
    {
        static void Main(string[] args)
        {
            DisplayDADStats();
        }

        public static void DisplayDADStats()
        {
            // Get access to the AppDomain for the current thread.
            AppDomain defaultAD = AppDomain.CurrentDomain;

            // Print out various stats about this domain.
            Console.WriteLine("Name of this domain: {0}", defaultAD.FriendlyName);
            Console.WriteLine("ID of domain in this process: {0}", defaultAD.Id);
            Console.WriteLine("Is this the default domain?: {0}", defaultAD.IsDefaultAppDomain());
            Console.WriteLine("Base directory of this domain: {0}", defaultAD.BaseDirectory);
        }
    }
}

// Output:
Name of this domain: AppDomain.exe
ID of domain in this process: 1
Is this the default domain?: True
Base directory of this domain: E:\CSPrograms\CSharp-MultiThreading\

जब ये Program Run होता है, तो सबसे पहले निम्नानुसार Statement Execute होता है:

AppDomain defaultAD = AppDomain.CurrentDomain;

ये Statement AppDomain Type defaultAD नाम का एक Object Create करता है और उसमें Current Program को ही Application Domain के रूप में Use कर लेता है। यानी हम Current Program को ही Run होने वाले Process के Application Domain की तरह Access करना चाहते हैं।

फिर हमने इस defaultAD Object के साथ FriendlyName Property को Use किया है, जो कि हमारे Application के नाम को Represent करता है और Id Property का प्रयोग करके हमने हमारे Current Application के ID को Display किया है, जो कि 1 है।

चूंकि हमारा Current Application ही Windows द्वारा Create होने वाले Process का पहला Application Domain है, इसलिए यही हमारा Default Application Domain होने की वजह से तीसरे Statement में Used IsDefaultAppDomain() Method True Return कर रहा है।

जबकि अन्तिम Statement में हमने BaseDirectory Property को Use किया है, जो कि हमारे Current Program यानी AppDomain की Base Directory के Path को Return कर रहा है। AppDomain के GetAssemblies() Method का प्रयोग करके हम किसी Specific Application Domain में Loaded विभिन्न .NET Assemblies की List भी प्राप्त कर सकते हैं।

उदाहरण के लिए यदि हम ये जानना चाहते हैं कि हमारा Current Program जब Application Domain की तरह किसी Process में Load होता है, तो किन-किन Assemblies को उपयोग में लेता है, तो इस जरूरत को पूरा करने के लिए हम निम्नानुसार एक Program बना सकते हैं और उसमें GetAssemblies() Method को Use करके इस बात का पता लगा सकते हैं:

File Name: AppDomainUsedAssemblies.cs
using System;
using System.Linq;
using System.Diagnostics;
using System.Reflection;

namespace CSharpMultiThreading
{
    class ApplicationDomain
    {
        static void Main(string[] args)
        {
            DisplayDADStats();
        }

        public static void DisplayDADStats()
        {
            // Get access to the AppDomain for the current thread.
            AppDomain defaultAD = AppDomain.CurrentDomain;
            Assembly[] loadedAssemblies = defaultAD.GetAssemblies();

            foreach (Assembly a in loadedAssemblies)
            {
                Console.WriteLine("-> Name: {0}", a.GetName().Name);
                Console.WriteLine("-> Version: {0}\n", a.GetName().Version);
            }
        }
    }
}

// Output:
-> Name: mscorlib
-> Version: 4.0.0.0

-> Name: AppDomainUsedAssemblies
-> Version: 0.0.0.0

जैसाकि इस Output द्वारा हम समझ सकते हैं कि हमारा Current Program भी Run होने के लिए mscorlib AppDomainUsedAssemblies नाम की दो Assemblies को उपयोग में लेते हुए Run हो रहा है।

इसी तरह से जब भी कोई नई Assembly किसी Specified Application Domain में Load होती है, CLR एक Notification Generate करता है, जिसके माध्‍यम से हम AssemblyLoad Event को उपयोग में लेते हुए किसी अन्‍य काम को पूरा कर सकते हैं।

इस Event को AssemblyLoadEventHandler Delegate के Against Use किया जाता है, जो कि किसी भी ऐसे Method को Callback कर सकता है, जो कि पहले Parameter के रूप में एक System.Object Type Argument Accept करता हो और दूसरे Parameter के रूप में AssemblyLoadEventArgs Type का Parameter लेता हो।

इस Event को Use करते हुए हम निम्नानुसार एक Program Create कर सकते हैं, जो कि किसी Assembly के Load होने के Response में उस Loaded Assembly की Information को Console में Output के रूप में Display करता है:

File Name: AssemblyLoaededInAppDomainNotification.cs
using System;
namespace CSharpMultiThreading
{
    class ApplicationDomain
    {
        static void Main(string[] args)
        {
            DisplayDADStats();
        }

        public static void DisplayDADStats()
        {
            // Get access to the AppDomain for the current thread.
            AppDomain defaultAD = AppDomain.CurrentDomain;
            defaultAD.AssemblyLoad += (o, s) =>
            {
                Console.WriteLine("{0} has been loaded in current AppDomain", 
	s.LoadedAssembly.GetName().Name);
            };
        }
    }
}

जैसे ही हम इस Program को Run करते हैं, तो इस Program को Run करने के लिए जो Process Execute होता है, जिसमें ये Program एक Default AppDomain की तरह Store होता है, उसमें जब भी कोई नया Assembly Load होता है, इस Program का निम्न Code Execute हो जाता है:

       defaultAD.AssemblyLoad += (o, s) =>
       {
           Console.WriteLine("{0} has been loaded in current AppDomain", s.LoadedAssembly.GetName().Name);
       };

और Output के रूप में हमें उस Dynamically Load होने वाली Assembly का नाम Console में दिखाई देने लगता है।

C# in Hindiये Article इस वेबसाईट पर Selling हेतु उपलब्‍ध EBook C#.NET in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी। 

C#.NET in Hindi | Page:908 | Format: PDF

BUY NOW GET DEMO REVIEWS