C# Raise Event

हालांकि triggeredEvent जैसे किसी Delegate Type Event Object की Invocation List में Execute होने वाले Callback Event Handlers की Information तो होती है। लेकिन ये तब तक Invoke नहीं होते, जब तक कि triggeredEvent Object को Method की तरह Invoke न किया जाए और जब हम किसी EventHandler Delegate Type के triggeredEvent जैसे किसी Object के साथ Parenthesis का प्रयोग करके उसे Invoke करते हैं, तो इस प्रक्रिया को Event Trigger होना या Event Fire होना या Event Raise होना कहा जाता है।

क्योंकि जैसे ही हम EventHandler Delegate Type के triggeredEvent जैसे किसी Object को Invoke करते हैं, उसकी Invocation List में Stored सभी Callbacks यानी Event Handlers Invoke हो जाते हैं, जो कि वही Callback Event Handler Methods होते हैं, जिनके लिए Subscriber ने Notification प्राप्त करने के लिए Register किया जाता है।

यानी triggeredEvent Object के साथ Parenthesis का प्रयोग करके Invoke करना ही Subscribers के लिए इस बात का Notification होता है कि वह Event Trigger हुआ है, जिसके लिए Subscribers ने Register किया है। परिणामस्वरूप उस Event के Trigger होने के साथ Associated सभी Event Handlers Execute हो जाते हैं, जो कि triggeredEvent Object की Invocation List में Stored होते हैं।

चूंकि triggeredEvent जैसा Event Member केवल उन Callback Event Handlers को Hold करता है, जिन्हें Invoke करना है। इसलिए जब तक Event Fire नहीं होता यानी triggeredEvent जैसे Event Member के साथ Parenthesis का प्रयोग नहीं किया जाताए तब तक कोई Acton Perform नहीं होता। इसलिए कोई Action Perform हो, इससे पहले हमें कुछ Tests कर लेने जरूरी होते हैं।

उदाहरण के लिए इससे पहले कि triggeredEvent Fire हो, हमें ये Check कर लेना चाहिए कि कहीं triggeredEvent में null तो नहीं है, जो कि इस बात का Indication होता है कि triggeredEvent के Fire होने के लिए कोई Callback Event Handler Subscribed नहीं है, जो Execute हो।

इसलिए यदि हम पिछले दोनों काम यानी Event Declaration Event Subscription करने के बाद triggeredEvent Event को Fire करना चाहें, तो हमें निम्नानुसार Code Statement का प्रयोग करना होता है:

	. . .
	if( triggeredEvent != null)
		triggeredEvent(parameters);		//Raise or Trigger the Event 
	. . .

इस तरह से अब यदि हम चाहें तो हमारी Publisher Class को पूरी तरह से Define कर सकते हैं क्योंकि एक Event Handling Mechanism से सम्बंधित पांचों Code Parts हमारे पास हैं और C# Event से सम्बंधित सभी पांचों Code Blocks को निम्नानुसार Program द्वारा Define कर सकते हैं:

File Name: EventExample.cs
using System;

namespace CSharpEevents
{
    delegate void Handler();			//Delegate Type Declared

    class Publisher
    {
        public event Handler valueChanged;		//Event Declared

        public void FireEvent(int value)
        {
            if (value == 3 && valueChanged != null)
                valueChanged();				//Raise or Trigger the Event 
        }
    }

    class Subscriber
    {
        public Subscriber(Publisher publisher)	//Subscribing for Triggered Event
        {
            publisher.valueChanged += EventHandler;
        }

        public void EventHandler()	//Callback Event Handler to be called in Response of Event
        {
            Console.WriteLine("valueChanged Event Fired Successfully.");
        }
    }

    class UsingEvent
    {
        public static void Main()
        {
            Publisher evtGenerator = new Publisher();
            Subscriber eventListener = new Subscriber(evtGenerator);

            int number;
            do
            {
                Console.Write("Enter a Number: ");
                number = Convert.ToInt32(Console.ReadLine());

                evtGenerator.FireEvent(number);

                if (number == 3)
                    return;
                else
                    Console.WriteLine("Event Not Fired. Try Something Else.\n");
            } while (number != 3);
        }
    }
}

// Output:
   Enter a Number: 1
   Event Not Fired. Try Something Else.

   Enter a Number: 5
   Event Not Fired. Try Something Else.

   Enter a Number: 3
   valueChanged Event Fired Successfully.

यदि हम इस Program को Event के रूप में समझने की कोशिश करें, तो ये Program थोडा Confusing महसूस हो सकता है। लेकिन यदि हम इस Program को Normal Delegate की तरह समझें, तो आसानी से इसके Flow को समझ सकते हैं।

इस Program में सबसे पहले निम्नानुसार Statement द्वारा एक Delegate Create किया गया है, ताकि हम इस Delegate के किसी Object में उन Methods को Add कर सकें, जिन्हें Delegate के माध्‍यम से Invoke करना है:

delegate void Handler();                                   //Delegate Type Declared

फिर हमने Publisher नाम की एक Class Create की है और उसमें Member के रूप में निम्नानुसार valueChanged नाम का एक Custom Event Specify किया है:

public event Handler valueChanged;            //Event Declared

और FireEvent() नाम का निम्नानुसार एक Method Define किया है, जो Parameter के रूप में एक Integer Value Accept करता है:

        public void FireEvent(int value)
        {
            if (value == 3 && valueChanged != null)
                valueChanged();		//Raise or Trigger the Event 
        }

इस Method में एक if Statement के बीच हमने इस बात को Check किया है कि valueChanged नाम के Delegate Type के Event Object की Invocation List में कोई Callable Method Exist है या नहीं और Parameter के रूप में आने वाला मान 3 है या नहीं।

यदि इस Method को Call करते समय Parameter के रूप में मान 3 Specify किया गया हो और valueChanged Delegate की Invocation List में एक भी Callback Method का Reference Exist हो, तो ये Method valueChanged() Delegate को Execute कर देता है, जो कि हमारे Program में एक Event को Represent कर रहा है।

यानी यदि दोनों स्थितियां उपयुक्त हों, तो FireEvent() नाम का Method Delegate की Invocation List में Specified सभी Callback Methods यानी Event Handlers को Execute कर देता है।

लेकिन Publisher Class में Defined FireEvent() Method जिन Callbacks को Invoke करने के लिए valueChanged Delegate Object को Invoke करता है यानी valueChanged Event को Trigger करता है, उन्हें पहले इस valueChanged Delegate Object में Add करना होता है।

अत: हमने Subscriber नाम की एक और Class Define की है, जो कि अपने Constructor में Parameter के रूप में Publisher Class के उस Object का Reference Accept करता है, जिसके valueChanged Delegate में Callback Method को Add करना है।

चूंकि हमारे Program में PublisherSubscriber दोनों ही Classes समान Namespace में हैं। इसलिए जब इस Constructor में किसी Publisher Class के Object का Reference Parameter के रूप में Pass किया जाता है, तब Parameter के रूप में जिस Publisher Class के Object का Reference आता है, उसी Publisher Class के Object के valueChanged Delegate Object में EventHandler नाम के Callback Method का Reference Pass कर दिया जाता है।

    class Subscriber
    {
        public Subscriber(Publisher publisher)	//Subscribing for Triggered Event
        {
            publisher.valueChanged += EventHandler;
        }

        public void EventHandler()	//Callback Event Handler to be called in Response of Event
        {
            Console.WriteLine("valueChanged Event Fired Successfully.");
        }
    }

PublisherSubscriber Classes Define करने के बाद हमने हमारे इस Program के Main() Method में निम्नानुसार तरीके से Publisher व Subscriber Type के दो Objects Create किए हैं:

Publisher evtGenerator = new Publisher();
Subscriber eventListener = new Subscriber(evtGenerator);

इन Statements के आधार पर evtGenerator Publisher Type का वह Object है, जो कि valueChanged Event Trigger कर सकता है, जबकि Subscriber Type का eventListener Object वह Object है, जो कि evtGenerator के valueChanged Event के लिए Notify होना चाहता है।

यानी eventListener Object चाहता है कि जब भी कभी evtGenerator Object, valueChanged Event Fire करे, यानी valueChanged() Delegate Execute हो, तो उसके Execute होते ही Subscriber Class में Defined EventHandler() नाम का Method Execute हो जाए।

इसीलिए हमने उपरोक्तानुसार Specified दूसरे Statement में Subscriber() Constructor में Publisher Type के evtGenerator Object के Reference को Parameter के रूप में Pass किया है, जो कि Subscriber Class के निम्नानुसार Constructor में Defined publisher नाम के Reference Variable में Store हो जाता है:

        public Subscriber(Publisher publisher)	//Subscribing for Triggered Event
        {
            publisher.valueChanged += EventHandler;
        }

चूंकि जब हम Parameter के रूप में किसी Reference Type को Specify करते हैं, तो Method में Formal Parameter के रूप में पूरे Object का Copy Pass नहीं होता बल्कि Actual Parameter के रूप में Object का केवल Reference ही Pass होता है।

इसलिए जब Subscriber() Constructor में हम Publisher Type के evtGenerator Object को Pass करते हैं, तो जिस Object को UsingEvent Class में evtGenerator द्वारा Refer किया जा रहा होता है, उसी Object को अब Subscriber() Constructor में publisher द्वारा Refer किया जाता है।

चूंकि Publisher Type का Reference Variable publisher, उसी Object को Refer कर रहा है, जिसे UsingEvent Type में evtGenerator Reference कर रहा है और evtGenerator Object में Exist Event Object valueChanged Declared है जो कि एक Handler Delegate Type है। इसलिए Subscriber() Constructor द्वारा जब हम EventHandler नाम के Callback Event Handler Method को निम्नानुसार Statement द्वारा publisher द्वारा Referenced Object के Delegate में Add किया जाता है:

publisher.valueChanged += EventHandler;

तो वह Callback Event Handler वास्तव में evtGenerator Object के valueChanged नाम के Delegate Object में Store हो जाता है।

इस तरह से इन दोनों Statements द्वारा Subscriber Class का Object, Publisher Class के Object के माध्‍यम से Publisher Class के Object द्वारा Trigger होने वाले valueChanged Event के लिए EventHandler नाम के एक Method को Callback के रूप में Publisher Class के Object के valueChanged Delegate में Add करते हुए Subscribe करता है।

Subscriber Class के Object के किसी Publisher Class के Object द्वारा Trigger होने वाले Event (Delegate Invocation like valueChanged()) के लिए Notification प्राप्त करने का मतलब यही है कि Subscriber ने जिस Callback Method को Publisher Class के Object के Delegate (valueChanged)  में Add किया है, वह EventHandler Method Execute हो जाए।

यानी Subscriber Class के Object द्वारा Publisher Class के Object के किसी Delegate (Event) में Add किए गए Callback Method का Delegate के Execution (Trigger) के कारण Invoke हो जाना ही Subscriber Class के Object का Notify होना कहलाता है।

जब एक बार Event Trigger करने वाला Publisher व उस Trigger होने वाले Event को Listen करने वाला Listener दोनों Objects Create हो जाते हैं और Subscriber जब Publisher से Trigger होने वाले Event को Listen करने के लिए Register कर लेता है, यानी अपने किसी Callback Event Handler को Event Delegate Object में Add कर देता है, उसके बाद Publisher से उस Event को Fire करने के लिए हम FireEvent() नाम का Method Call किया जा सकता है।

जब Event Trigger करने वाला Subscriber Type evtGenerator Object तथा Publisher द्वारा Trigger होने वाले Event के Response में Execute होने वाले Callback Method को Specify करने के लिए Subscriber Type का eventListener Object Create हो जाता है, तब Main() Method में एक do…while Loop चलाया जाता है और User से एक संख्‍या Input करने के लिए कहा जाता है।

User जो संख्‍या Input करता है, उसे निम्नानुसार तरीके से evtGenerator Object के लिए FireEvent() Method Call करके उसमें Parameter के रूप में Pass किया जाता है:

evtGenerator.FireEvent(number);

परिणामस्वरूप FireEvent() Method number के रूप में Pass होने वाले मान के आधार पर निम्नानुसार if Statement Execute करके इस बात का पता लगाता है कि Parameter के रूप में आने वाला मान 3 है या नहीं:

        public void FireEvent(int value)
        {
            if (value == 3 && valueChanged != null)
                valueChanged();		//Raise or Trigger the Event 
        }

यदि FireEvent() Method के Parameter के रूप में मान 3 Pass किया जाता है, तो if Statement इस बात को भी Check करता है कि evtGenerator Object के valueChanged नाम का जो Event Delegate है, उसमें कोई Callback Event Handler Method Registered है या नहीं।

चूंकि हमने Subscriber Type का eventListener नाम का एक Object Create किया है, जो कि evtGenerator Object द्वारा Trigger होने वाले valueChanged Event Delegate के लिए Registered है और Registration के रूप में EventHandler() नाम के Callback Method को valueChanged नाम के Event Delegate में Add कर रहा है। इसलिए evtGenerator Object के valueChanged Event Delegate की Invocation List में EventHandler() नाम का Callback Method Exist होता है।

इसलिए यदि FireEvent() Method में Pass किया गया मान 3 हो, तो if Statement true हो जाता है और valueChanged() Event Delegate को Execute कर देता है। इस Delegate के Execute होते ही Subscriber Type के eventListener Object द्वारा Registered EventHandler() Callback Method Execute हो जाता है। परिणामस्वरूप हमें Output में निम्नानुसार Message प्राप्त होता है, जो कि हमने Subscriber Class में Defined EventHandler() Method में Specify किया था:

valueChanged Event Fired Successfully.

इस तरह से अब यदि हम सरल ब्दों में समझें, तो कोई Event किसी Specific Situation या Action को Represent करता है और इस Specific Situation या Action के Response में हम किसी Callback Event Handler को Execute करते हैं। जबकि Response के रूप में हम जिस Callback Event Handler Method को Execute करना चाहते हैं, उसे Subscriber Class के Object के माध्‍य से Publisher Class के Object के Event Delegate की Invocation List में Add करते हैं।

परिणामस्वरूप जैसे ही Publisher Class का Object किसी Event को Fire करता है, उस Event के Fire होने के साथ ही उस Event के लिए Subscribed सभी Callback Event Handlers Response के रूप में Execute हो जाते हैं।

जब हम कोई Event Publisher Class Define कर देते है, तो उस Publisher Class द्वारा Trigger होने वाले Event के लिए हम जितने चाहें, उतने Subscribers को Subscribe करवा सकते हैं और सभी Subscribed Objects किसी न किसी Callback Method को Event की Invocation List में Add कर सकते हैं। परिणामस्वरूप जितने भी Objects किसी Event के लिए Subscribe करते हैं, Event के Fire होने पर उन सभी Objects द्वारा Added Callback Methods Invoke हो जाते हैं।

यानी हमें किसी Event को Trigger करने के लिए केवल एक ही बार Publisher Class Define करना होता है। फिर उस Event के लिए हम जितने चाहें उतने Subscribers को Subscribe करवा सकते हैं।

इसलिए यदि हम हमारे इस पिछले Program में ही valueChanged Event के लिए एक और Subscriber Class Create करना चाहें, तो अपने इसी Program को हम निम्नानुसार Modify कर सकते हैं:

File Name: EventExample1.cs
using System;

namespace CSharpEevents
{
    delegate void Handler();
    class Publisher
    {
        public event Handler valueChanged;		//Event Declared

        public void FireEvent(int value)
        {
            if (value == 3 && valueChanged != null)
                valueChanged();				//Raise or Trigger the Event 
        }
    }

    class Subscriber
    {
        public Subscriber(Publisher publisher)
        {
            publisher.valueChanged += EventHandler;
        }

        public void EventHandler()
        {
            Console.WriteLine("Event Handler of Subscriber for valueChanged Event.");
        }
    }

    class Subscriber1
    {
        public Subscriber1(Publisher publisher)
        {
            publisher.valueChanged += EventHandler;
        }

        public void EventHandler()
        {
            Console.WriteLine("Event Handler of Subscriber1 for valueChanged Event.");
        }
    }

    class UsingEvent
    {
        public static void Main()
        {
            Publisher evtGenerator = new Publisher();
            Subscriber eventListener = new Subscriber(evtGenerator);
            Subscriber1 eventListener1 = new Subscriber1(evtGenerator);

            int number;
            do
            {
                Console.Write("Enter a Number: ");
                number = Convert.ToInt32(Console.ReadLine());
                evtGenerator.FireEvent(number);

                if (number == 3)
                    return;
                else
                    Console.WriteLine("Event Not Fired. Try Something Else.\n");
            } while (number != 3);
        }
    }
}

// Output:
   Enter a Number: 1
   Event Not Fired. Try Something Else.

   Enter a Number: 2
   Event Not Fired. Try Something Else.

   Enter a Number: 3
   Event Handler of Subscriber for valueChanged Event.
   Event Handler of Subscriber1 for valueChanged Event.

इस Program में हमने Subscriber1 नाम की एक और Class Define की है, जो कि Exactly Subscriber Class की तरह ही है। फिर Main() Method में निम्नानुसार तरीके से इस Subscribed1 Class के Object के लिए भी हमने Publisher Class के Object से Connection बनाया है:

Subscriber1 eventListener1 = new Subscriber1(evtGenerator);

ताकि जब evtGenerator Object के लिए FireEvent() Method द्वारा valueChanged नाम का Event Fire हो, तो इस Subscriber1 Class के Object द्वारा Registered EventHandler भी Execute हो जाए।

चूंकि Subscriber Subscriber1 दोनों ही Class के Objects eventListenereventListener1, Publisher Class के Object evtGenerator के साथ ही Registered हैं। इसलिए जैसे ही evtGenerator Object के लिए FireEvent() Method को Call करके valueChanged Event को Fire किया जाता है, दोनों ही Event Listeners के Callback EventHandler() Methods Execute हो जाते हैं और हमें उपरोक्तानुसार Output प्राप्त हो जाता है।

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

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

BUY NOW GET DEMO REVIEWS