C# Background Thread

C# Background Thread: पिछले कुछ उदाहरणों में हमने Primary Thread को इस बात का Instruction देने के लिए कि Secondary Thread ने अपना काम कर दिया है, कई अटपटे तरीके अपना, हैं। यानी हमने Asynchronous Delegates को Use करते समय एक Simple Boolean Variable द्वारा Primary Thread को इस बात का Instruction दिया था, जो कि एक उपयुक्त Solution नहीं था। क्योंकि विभिन्न Secondary Threads को Primary Thread के माध्‍यम से ही Create किया जाता है और किसी Process के विभिन्न Threads समान Data को Share कर सकते हैं।

इसलिए Primary Thread में हमेंशा Thread.Sleep() Method को एक निश्चित समय के लिए Call करना व इस बात को Check करना कि किसी Secondary Thread ने अपने काम को पूरा किया या नहीं, कोई व्‍यवस्थित तरीका नहीं है।

क्योंकि यदि हम Thread.Sleep() Method द्वारा Secondary Thread के पूरा होने का Wait करते हैं, तो हो सकता है कि हमारा Secondary Thread उस Specified Time Amount से पहले ही Complete हो जाए और Main Thread बेवजह ही Suspended रहे।

यानी सबसे बेहतर Solution यही है कि Primary Thread केवल तभी तक Secondary Thread के Complete होने का Wait करे, जब तक कि Secondary Thread अपना काम पूरा नहीं कर लेता। जैसे ही Secondary Thread का काम पूरा होता है, Primary Thread को तुरन्त इस बात का Notification मिल जाना चाहिए।

इस जरूरत को पूरा करने का एक Thread-Safe Simple तरीका ये है कि हम किसी Thread को केवल तब तक Wait करने के लिए Instruct करें, जब तक कि किसी अन्‍य Thread का काम पूरा नहीं हो जाता और ऐसा करने के लिए हम AutoResetEvent Class को Use कर सकते हैं।

जिस Thread को Wait करना होता है, उस Thread में AutoResetEvent Type का एक Object Create करना होता है और इसके Constructor में false Pass करना होता है, जो इस बात का Instruction होता है कि Current Thread अभी तक Notify नहीं हुआ है। फिर हमें उस Program Point पर WaitOne() Method को Call करना होता है, जहां हम Wait करना चाहते हैं। यदि हम इस पूरी प्रक्रिया को अपने पिछले Program पर Apply करें, तो हमारा पिछला Program कुछ निम्नानुसार बन सकता है:

File Name: AutoSaveEvent.cs
using System;
using System.Threading;
using System.Windows.Forms;

namespace CSharpMultiThreading
{
    class AddParams
    {
        public int a, b;

        public AddParams(int numb1, int numb2)
        {
            a = numb1;
            b = numb2;
        }
    }

    class UsingParameterizedThreadStartDelegate
    {
        static void Add(object data)
        {
            if (data is AddParams)
            {
                Console.WriteLine("ID of thread in Add(): {0}",
                Thread.CurrentThread.ManagedThreadId);
                AddParams ap = (AddParams)data;
                Console.WriteLine("{0} + {1} is {2}", ap.a, ap.b, ap.a + ap.b);
            }

            // Tell other thread we are done.
            waitHandle.Set();
        }

        private static AutoResetEvent waitHandle = new AutoResetEvent(false);

        static void Main(string[] args)
        {
            Console.WriteLine("ID of thread in Main(): {0}", Thread.CurrentThread.ManagedThreadId);

            // Make an AddParams object to pass to the secondary thread.
            AddParams ap = new AddParams(10, 10);
            ParameterizedThreadStart secondaryThreadCode = new ParameterizedThreadStart(Add);
            Thread t = new Thread(secondaryThreadCode);
            t.Start(ap);

            // Wait here until you are notified!
            waitHandle.WaitOne();
            Console.WriteLine("Other thread is done!");
        }
    }
}

// Output:
   ID of thread in Main(): 1
   ID of thread in Add(): 3
   10 + 10 is 20
   Other thread is done!

इस Program में हमने सबसे पहले अपनी Main Class में निम्नानुसार एक AutoResetEvent Type का Object Create किया है:

private static AutoResetEvent waitHandle = new AutoResetEvent(false);

फिर Main Method में निम्नानुसार तरीके से waitHandle Object के साथ WaitOne() Method को Call किया है, जो Main Thread को तब तक Wait करने का Instruction देता है, जब तक कि वह उस Thread के Completion का Notification प्राप्त नहीं करताए जिसके Complete होने के बाद इसे आगे बढना है:

// Wait here until you are notified!
waitHandle.WaitOne();
Console.WriteLine(“Other thread is done!”);

Calling Thread को इस प्रकार से Wait करने हेतु Program करने के बाद हमें उस Secondary Thread से इस बात का Instruction देना होता है कि वह Complete हो चुका है, ताकि उपरोक्त Code के माध्‍यम से Main Thread इस बात का Notification प्राप्त करके अपना आगे का काम Continue कर सके। इस जरूरत को पूरा करने के लिए हमें हमारे Secondary Thread में निम्नानुसार Set() Method को Use करना होता है:

// Tell other thread we are done.
waitHandle.Set();

जैसे ही Add() Method पूरी तरह से Complete होता है, वह उपरोक्त Code द्वारा Calling Thread को एक Notification जारी करता है कि उसने अपना काम Complete कर लिया है। परिणामस्वरूप Waiting कर रहे Calling Thread को जैसे ही ये Notification प्राप्त होता है, वह अपना आगे का काम Continue कर देता है।

Foreground Threads and Background Threads

Threads मूलत: दो प्रकार के होते हैं, जिन्हें Foreground Thread व Background Threads के नाम से जाना जाता है। Foreground Threads में ये Ability होती है कि वे Current Application को Terminate होने से रोक सकते हैं। यानी CLR किसी Application को तब तक Shut Down नहीं कर सकता यानी किसी Hosting AppDomain को Unload नहीं कर सकताए जब तक कि Foreground Thead का End नहीं हो जाता।

जबकि Background Threads जिसे अक्सर Daemon Thread भी कहते हैं, को CLR एक Expandable Path of Execution की तरह देखता है, जिसे किसी भी समय Ignore किया जा सकता है भले ही वे किसी काम को पूरा करने के लिए Continually Run ही क्यों न कर रहे हों।

अत: यदि सभी Foreground Threads Terminated हो चुके हों तो सभी Background Threads Automatically उस समय Terminate हो जाते हैं, जब CLR उस Application Domain को Unload करता है, जिसमें वह Background Thread होता है।

यहां ध्‍यान देने वाली बात ये है कि Foreground व Background Threads, Primary Thread व Secondary Thread (Worker Thread) के Synonymous नहीं होते। Default रूप से हम ThreadStart() Method का प्रयोग करके जो भी Thread Create करते हैं, वे सभी Automatically Foreground Thread ही बनते हैं, जिन्हें AppDomain तब तक Unload नहीं करताए जब तक कि Thread of Execution अपना काम पूरी तरह से Complete नहीं कर लेते।

उदाहरण के लिए मानलो कि हम Printer.PrintNumbers() को किसी Secondary Thread पर Invoke करना चाहते हैं, जो कि एक Background Thread की तरह काम करे। तो इस जरूरत को पूरा करने के लिए यानी किसी Thread को एक Background Thread बनाने के लिए हमें केवल उस Thread की IsBackground Property को true Set करना होता है। जैसे:

File Name: CreatingBackgroundThread.cs
using System;
using System.Threading;
using System.Windows.Forms;

namespace CSharpMultiThreading
{
    public class Printer
    {
        //Step1: Method to be executed as Secondary Thread
        public void PrintNumbers()
        {
            // Display Thread info.
            Console.WriteLine("-> {0} is executing PrintNumbers()", Thread.CurrentThread.Name);

            // Print out numbers.
            Console.Write("Your numbers: ");
            for (int i = 0; i < 10; i++)
            {
                Console.Write("{0}, ", i);
                Thread.Sleep(2000);
            }
        }
    }

    class UsingThreadStartDelegate
    {
        static void Main(string[] args)
        {
            Console.Write("Do you want [1] or [2] threads? ");
            string threadCount = Console.ReadLine();

            // Name the current thread.
            Thread primaryThread = Thread.CurrentThread;
            primaryThread.Name = "Primary";

            // Display Thread info.
            Console.WriteLine("-> {0} is executing Main()", Thread.CurrentThread.Name);

            // Make worker class.
            Printer p = new Printer();

            //Step2: ThreadStart Delegate Object
            ThreadStart secondaryThreadCode = new ThreadStart(p.PrintNumbers);

            switch (threadCount)
            {
                case "2":
                    // Step3: Create New Thread.
                    Thread backgroundThread = new Thread(secondaryThre2adCode);

                    // Step4: Initialize Properties with Newly Created Thread.
                    backgroundThread.Name = "Secondary";
                    backgroundThread.IsBackground = true;	//Creating Background Thread

                    // Step5: Start the Newly Created Thread.
                    backgroundThread.Start();
                    break;

                case "1":
                    p.PrintNumbers();
                    break;

                default:
                    Console.WriteLine("I don't know what you want...you get 1 thread.");
                    goto case "1";
            }
            // Do some additional work.
            MessageBox.Show("I'm busy!", "Work on main thread...");
        }
    }
}

जब हम इस Program के Secondary Thread को निम्नानुसार Statement का प्रयोग करके एक Background Thread बना देते हैं:

backgroundThread.IsBackground = true;           //Creating Background Thread

तो उस स्थिति में जब हम इस Program को Run करते हैं, तो Main Thread द्वारा Create होने वाले Message Box जो कि हमारे Primary Thread द्वारा Create हो रहा है, को जैसे ही Close करते हैं, हमारा पूरा Program Terminate हो जाता है। क्योंकि हमारा Message Box एक Foreground Process में Create हो रहा है। इसलिए इसे Close करते ही सभी Background Threads Automatically Terminate हो जाते हैं।

जबकि इसी Program को जब हम Normal Foreground Secondary Thread के रूप में Run करते हैं, तो Message Box को Close करने के बावजूद Program पूरी तरह से Terminate नहीं होता। क्योंकि उस स्थिति में हमारा Secondary Thread जब तक Finish नहीं हो जाताए तब तक Primary Thread भी Terminate नहीं होता। क्योंकि सामान्‍यत: सभी Foreground Secondary Threads के Terminate होने के बाद ही Primary Thread Terminate हो सकता है।

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

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

BUY NOW GET DEMO REVIEWS