.NET में .NETResetEvent और AutoResetEvent के बीच क्या अंतर है?


532

मैंने इस पर प्रलेखन पढ़ा है और मुझे लगता है कि मैं समझता हूं। AutoResetEventकोड से गुजरने पर एक रीसेट करता है event.WaitOne(), लेकिन एक ManualResetEventनहीं करता है।

क्या ये सही है?


2
मई इस अंतर को समझने में मदद करेगा youtube.com/watch?v=xaaRBh07N34
विनोद श्रीवास्तव

जवाबों:


919

हाँ। यह एक टोलबॉथ और एक दरवाजे के बीच अंतर की तरह है। ManualResetEventदरवाजा है, जो बंद हो (रीसेट) मैन्युअल रूप से की जरूरत है। AutoResetEventएक tollbooth है, एक गाड़ी से जाने के लिए अनुमति और इससे पहले कि अगले एक के माध्यम से प्राप्त कर सकते हैं स्वचालित रूप से बंद हो रहा।


166
यह एक महान सादृश्य है।
17

इससे भी बदतर, वेटऑन को सेट करने से लंबे समय तक इंतजार न करें, या इसे बीच में रीसेट किया जाएगा। उसके साथ कई परित्यक्त धागे थे।
ओलिवर फ्रेडरिक

24
या एक दरवाजे और एक टर्नस्टाइल की तरह।
कांस्टेंटिन

9
ओह, इसलिए उन्हें नाम दिया गया है कि वे क्या हैं।
अरलेन बीलर

1
@DanGoldstein अच्छी तरह से, क्योंकि यह बंद नहीं है और यदि कोई अन्य व्यक्ति यह चाहता है: msdn.microsoft.com/en-us/library/…
Phil N DeBlanc

124

बस कल्पना कीजिए कि AutoResetEventनिष्पादन WaitOne()और Reset()एक एकल परमाणु संचालन के रूप में।


16
सिवाय इसके कि अगर आपने एक वीकऑनसेट इवेंट पर एक एकल परमाणु ऑपरेशन के रूप में WaitOne और रीसेट को निष्पादित किया, तो यह अभी भी AutoResetEvent के लिए कुछ अलग करेगा। ManualResetEvent सभी प्रतीक्षा थ्रेड्स को उसी समय रिलीज़ करता है, जहाँ AutoResetEvent केवल एक प्रतीक्षा थ्रेड को रिलीज़ करने की गारंटी देता है।
मार्टिन ब्राउन

55

छोटा जवाब हां है। सबसे महत्वपूर्ण अंतर यह है कि एक AutoResetEvent केवल एक वेटिंग थ्रेड को जारी रखने की अनुमति देगा। दूसरी ओर एक मैन्युअलResetEvent धागे को अनुमति देता रहेगा, कई एक ही समय पर भी, तब तक जारी रखने के लिए जब तक आप इसे रोकने के लिए नहीं कहते (इसे रीसेट करें)।


36

यूसुफ अलबहारी द्वारा C # 3.0 संक्षेप पुस्तक से लिया गया

सी # में थ्रेडिंग - फ्री ई-बुक

एक मैन्युअलResetEvent AutoResetEvent पर एक भिन्नता है। यह इस बात में भिन्न होता है कि किसी थ्रेडऑन कॉल पर थ्रेड के द्वारा स्वचालित रूप से रीसेट होने के बाद यह स्वचालित रूप से रीसेट नहीं होता है, और इसलिए गेट की तरह कार्य करता है: कॉलिंग सेट गेट को खोलता है, जिससे गेट पर थ्रेडऑन की किसी भी संख्या की अनुमति मिलती है; कॉलिंग रीसेट गेट को बंद कर देता है, जिससे संभावित रूप से वेटरों की एक कतार उसके अगले खुलने तक जमा हो जाती है।

एक बार "स्पिन-स्लीपिंग" के संयोजन में एक बूलियन "गेटऑपेन" फ़ील्ड (वाष्पशील कीवर्ड के साथ घोषित) के साथ इस कार्यक्षमता का अनुकरण कर सकता है - बार-बार ध्वज की जांच करना, और फिर कुछ समय के लिए सो जाना।

ManualResetEvents का उपयोग कभी-कभी यह संकेत देने के लिए किया जाता है कि एक विशेष ऑपरेशन पूरा हो गया है, या यह कि एक थ्रेड का प्रारंभिक आरंभीकरण है और काम करने के लिए तैयार है।


19

मैंने ManualResetEventबनाम की समझ को स्पष्ट करने के लिए सरल उदाहरण बनाए AutoResetEvent

AutoResetEvent: मान लेते हैं कि आपके पास 3 श्रमिक सूत्र हैं। यदि उन थ्रेड्स में से कोई भी WaitOne()अन्य सभी 2 थ्रेड्स कॉल करेंगे, तो निष्पादन बंद हो जाएगा और सिग्नल की प्रतीक्षा करेगा। मैं मान रहा हूं कि वे उपयोग कर रहे हैं WaitOne()। जैसे की; अगर मैं काम नहीं करता तो कोई काम नहीं करता। पहले उदाहरण में आप देख सकते हैं

autoReset.Set();
Thread.Sleep(1000);
autoReset.Set();

जब आप कॉल करते हैं तो Set()सभी थ्रेड काम करेंगे और सिग्नल की प्रतीक्षा करेंगे। 1 सेकंड के बाद मैं दूसरा संकेत भेज रहा हूं और वे निष्पादित करते हैं और प्रतीक्षा करते हैं ( WaitOne())। इन लोगों के बारे में सोचें कि फुटबॉल टीम के खिलाड़ी हैं और अगर एक खिलाड़ी कहता है कि मैं तब तक इंतजार करूंगा जब तक कि प्रबंधक मुझे नहीं बुलाएगा, और अन्य तब तक इंतजार करेंगे जब तक प्रबंधक उन्हें जारी रखने के लिए नहीं कहता ( Set())

public class AutoResetEventSample
{
    private AutoResetEvent autoReset = new AutoResetEvent(false);

    public void RunAll()
    {
        new Thread(Worker1).Start();
        new Thread(Worker2).Start();
        new Thread(Worker3).Start();
        autoReset.Set();
        Thread.Sleep(1000);
        autoReset.Set();
        Console.WriteLine("Main thread reached to end.");
    }

    public void Worker1()
    {
        Console.WriteLine("Entered in worker 1");
        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker1 is running {0}", i);
            Thread.Sleep(2000);
            autoReset.WaitOne();
        }
    }
    public void Worker2()
    {
        Console.WriteLine("Entered in worker 2");

        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker2 is running {0}", i);
            Thread.Sleep(2000);
            autoReset.WaitOne();
        }
    }
    public void Worker3()
    {
        Console.WriteLine("Entered in worker 3");

        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker3 is running {0}", i);
            Thread.Sleep(2000);
            autoReset.WaitOne();
        }
    }
}

इस उदाहरण में आप स्पष्ट रूप से देख सकते हैं कि जब आप पहली बार हिट करते हैं तो Set()यह सभी थ्रेड्स को जाने देगा, फिर 1 सेकंड के बाद यह सभी थ्रेड्स को प्रतीक्षा करने का संकेत देता है! जैसे ही आप उन्हें फिर से सेट करते हैं WaitOne(), भले ही वे अंदर बुला रहे हों , वे भागते रहेंगे क्योंकि आपको Reset()उन सभी को रोकने के लिए मैन्युअल कॉल करना होगा।

manualReset.Set();
Thread.Sleep(1000);
manualReset.Reset();
Console.WriteLine("Press to release all threads.");
Console.ReadLine();
manualReset.Set();

यह रेफरी / खिलाड़ियों के संबंध के बारे में अधिक है, चाहे कोई भी खिलाड़ी घायल हो और दूसरों के खेलने के लिए इंतजार करना जारी रहेगा। यदि रेफरी प्रतीक्षा ( Reset()) कहता है, तो सभी खिलाड़ी अगले सिग्नल तक इंतजार करेंगे।

public class ManualResetEventSample
{
    private ManualResetEvent manualReset = new ManualResetEvent(false);

    public void RunAll()
    {
        new Thread(Worker1).Start();
        new Thread(Worker2).Start();
        new Thread(Worker3).Start();
        manualReset.Set();
        Thread.Sleep(1000);
        manualReset.Reset();
        Console.WriteLine("Press to release all threads.");
        Console.ReadLine();
        manualReset.Set();
        Console.WriteLine("Main thread reached to end.");
    }

    public void Worker1()
    {
        Console.WriteLine("Entered in worker 1");
        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker1 is running {0}", i);
            Thread.Sleep(2000);
            manualReset.WaitOne();
        }
    }
    public void Worker2()
    {
        Console.WriteLine("Entered in worker 2");

        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker2 is running {0}", i);
            Thread.Sleep(2000);
            manualReset.WaitOne();
        }
    }
    public void Worker3()
    {
        Console.WriteLine("Entered in worker 3");

        for (int i = 0; i < 5; i++) {
            Console.WriteLine("Worker3 is running {0}", i);
            Thread.Sleep(2000);
            manualReset.WaitOne();
        }
    }
}

13

autoResetEvent.WaitOne()

के समान है

try
{
   manualResetEvent.WaitOne();
}
finally
{
   manualResetEvent.Reset();
}

परमाणु ऑपरेशन के रूप में


यह केवल वैचारिक रूप से सही है, लेकिन व्यावहारिक रूप से नहीं। WaitOne और Reset के बीच एक संदर्भ स्विच हो सकता है; इससे सूक्ष्म कीड़े हो सकते हैं।
होफिंगरंडी

2
क्या आप इसे अब वोट कर सकते हैं? कोई भी व्यावहारिक रूप से यहां दूसरा कोड ब्लॉक नहीं करेगा, यह अंतर समझने की बात है।
वेजेनकोव

11

ठीक है, आम तौर पर एक ही धागे में 2 उत्तर जोड़ने के लिए यह एक अच्छा अभ्यास नहीं है, लेकिन मैं अपने पिछले उत्तर को संपादित / हटाना नहीं चाहता था, क्योंकि यह दूसरे तरीके से मदद कर सकता है।

अब, मैंने बनाया, बहुत अधिक व्यापक, और समझने में आसान है, रन-टू-लर्न कंसोल ऐप स्निपेट नीचे।

बस दो अलग-अलग कंसोल पर उदाहरणों को चलाएं, और व्यवहार का निरीक्षण करें। आपको वहां और अधिक स्पष्ट विचार मिलेगा कि पर्दे के पीछे क्या हो रहा है।

मैनुअल रीसेट इवेंट

using System;
using System.Threading;

namespace ConsoleApplicationDotNetBasics.ThreadingExamples
{
    public class ManualResetEventSample
    {
        private readonly ManualResetEvent _manualReset = new ManualResetEvent(false);

        public void RunAll()
        {
            new Thread(Worker1).Start();
            new Thread(Worker2).Start();
            new Thread(Worker3).Start();
            Console.WriteLine("All Threads Scheduled to RUN!. ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("Main Thread is waiting for 15 seconds, observe 3 thread behaviour. All threads run once and stopped. Why? Because they call WaitOne() internally. They will wait until signals arrive, down below.");
            Thread.Sleep(15000);
            Console.WriteLine("1- Main will call ManualResetEvent.Set() in 5 seconds, watch out!");
            Thread.Sleep(5000);
            _manualReset.Set();
            Thread.Sleep(2000);
            Console.WriteLine("2- Main will call ManualResetEvent.Set() in 5 seconds, watch out!");
            Thread.Sleep(5000);
            _manualReset.Set();
            Thread.Sleep(2000);
            Console.WriteLine("3- Main will call ManualResetEvent.Set() in 5 seconds, watch out!");
            Thread.Sleep(5000);
            _manualReset.Set();
            Thread.Sleep(2000);
            Console.WriteLine("4- Main will call ManualResetEvent.Reset() in 5 seconds, watch out!");
            Thread.Sleep(5000);
            _manualReset.Reset();
            Thread.Sleep(2000);
            Console.WriteLine("It ran one more time. Why? Even Reset Sets the state of the event to nonsignaled (false), causing threads to block, this will initial the state, and threads will run again until they WaitOne().");
            Thread.Sleep(10000);
            Console.WriteLine();
            Console.WriteLine("This will go so on. Everytime you call Set(), ManualResetEvent will let ALL threads to run. So if you want synchronization between them, consider using AutoReset event, or simply user TPL (Task Parallel Library).");
            Thread.Sleep(5000);
            Console.WriteLine("Main thread reached to end! ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);

        }

        public void Worker1()
        {
            for (int i = 1; i <= 10; i++)
            {
                Console.WriteLine("Worker1 is running {0}/10. ThreadId: {1}.", i, Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(5000);
                // this gets blocked until _autoReset gets signal
                _manualReset.WaitOne();
            }
            Console.WriteLine("Worker1 is DONE. ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);
        }
        public void Worker2()
        {
            for (int i = 1; i <= 10; i++)
            {
                Console.WriteLine("Worker2 is running {0}/10. ThreadId: {1}.", i, Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(5000);
                // this gets blocked until _autoReset gets signal
                _manualReset.WaitOne();
            }
            Console.WriteLine("Worker2 is DONE. ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);
        }
        public void Worker3()
        {
            for (int i = 1; i <= 10; i++)
            {
                Console.WriteLine("Worker3 is running {0}/10. ThreadId: {1}.", i, Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(5000);
                // this gets blocked until _autoReset gets signal
                _manualReset.WaitOne();
            }
            Console.WriteLine("Worker3 is DONE. ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);
        }
    }

}

मैनुअल रीसेट इवेंट आउटपुट

ऑटो रीसेट इवेंट

using System;
using System.Threading;

namespace ConsoleApplicationDotNetBasics.ThreadingExamples
{
    public class AutoResetEventSample
    {
        private readonly AutoResetEvent _autoReset = new AutoResetEvent(false);

        public void RunAll()
        {
            new Thread(Worker1).Start();
            new Thread(Worker2).Start();
            new Thread(Worker3).Start();
            Console.WriteLine("All Threads Scheduled to RUN!. ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("Main Thread is waiting for 15 seconds, observe 3 thread behaviour. All threads run once and stopped. Why? Because they call WaitOne() internally. They will wait until signals arrive, down below.");
            Thread.Sleep(15000);
            Console.WriteLine("1- Main will call AutoResetEvent.Set() in 5 seconds, watch out!");
            Thread.Sleep(5000);
            _autoReset.Set();
            Thread.Sleep(2000);
            Console.WriteLine("2- Main will call AutoResetEvent.Set() in 5 seconds, watch out!");
            Thread.Sleep(5000);
            _autoReset.Set();
            Thread.Sleep(2000);
            Console.WriteLine("3- Main will call AutoResetEvent.Set() in 5 seconds, watch out!");
            Thread.Sleep(5000);
            _autoReset.Set();
            Thread.Sleep(2000);
            Console.WriteLine("4- Main will call AutoResetEvent.Reset() in 5 seconds, watch out!");
            Thread.Sleep(5000);
            _autoReset.Reset();
            Thread.Sleep(2000);
            Console.WriteLine("Nothing happened. Why? Becasuse Reset Sets the state of the event to nonsignaled, causing threads to block. Since they are already blocked, it will not affect anything.");
            Thread.Sleep(10000);
            Console.WriteLine("This will go so on. Everytime you call Set(), AutoResetEvent will let another thread to run. It will make it automatically, so you do not need to worry about thread running order, unless you want it manually!");
            Thread.Sleep(5000);
            Console.WriteLine("Main thread reached to end! ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);

        }

        public void Worker1()
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Worker1 is running {0}/5. ThreadId: {1}.", i, Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(500);
                // this gets blocked until _autoReset gets signal
                _autoReset.WaitOne();
            }
            Console.WriteLine("Worker1 is DONE. ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);
        }
        public void Worker2()
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Worker2 is running {0}/5. ThreadId: {1}.", i, Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(500);
                // this gets blocked until _autoReset gets signal
                _autoReset.WaitOne();
            }
            Console.WriteLine("Worker2 is DONE. ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);
        }
        public void Worker3()
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Worker3 is running {0}/5. ThreadId: {1}.", i, Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(500);
                // this gets blocked until _autoReset gets signal
                _autoReset.WaitOne();
            }
            Console.WriteLine("Worker3 is DONE. ThreadId: {0}", Thread.CurrentThread.ManagedThreadId);
        }
    }

}

ऑटो रीसेट इवेंट आउटपुट


यह सब समझने का सबसे अच्छा तरीका था, कोड को कॉपी किया और कुछ चीजों को बदलते हुए यह सब भाग गया, इसे अब अच्छी तरह से समझ लिया है
JohnCris

8

AutoResetEvent एक बूलियन चर स्मृति में बनाए रखता है। यदि बूलियन चर गलत है, तो यह थ्रेड को ब्लॉक करता है और यदि बूलियन चर सत्य है तो यह थ्रेड को अनवरोधित करता है।

जब हम किसी AutoResetEvent ऑब्जेक्ट को इंस्टाल करते हैं, तो हम कंस्ट्रक्टर में बूलियन मान का डिफ़ॉल्ट मान पास करते हैं। नीचे एक AutoResetEvent ऑब्जेक्ट को तुरंत लिखने का सिंटैक्स है।

AutoResetEvent autoResetEvent = new AutoResetEvent(false);

WaitOne विधि

यह विधि वर्तमान थ्रेड को ब्लॉक करती है और अन्य थ्रेड द्वारा सिग्नल की प्रतीक्षा करती है। WaitOne विधि वर्तमान थ्रेड को स्लीप थ्रेड स्थिति में रखता है। अगर यह सिग्नल प्राप्त करता है तो वेटऑन विधि सही हो जाती है और दूसरा गलत हो जाता है।

autoResetEvent.WaitOne();

WaitOne विधि का दूसरा अधिभार निर्दिष्ट सेकंड की संख्या के लिए प्रतीक्षा करें। अगर इसे कोई संकेत नहीं मिलता है तो धागा अपना काम जारी रखता है।

static void ThreadMethod()
{
    while(!autoResetEvent.WaitOne(TimeSpan.FromSeconds(2)))
    {
        Console.WriteLine("Continue");
        Thread.Sleep(TimeSpan.FromSeconds(1));
    }

    Console.WriteLine("Thread got signal");
}

हमने 2 सेकंड को तर्क के रूप में पारित करके WaitOne विधि कहा। जबकि लूप में, यह 2 सेकंड के लिए सिग्नल की प्रतीक्षा करता है फिर यह अपना काम जारी रखता है। जब थ्रेड को सिग्नल मिला तो WaitOne सच हो जाता है और लूप को बाहर निकालता है और "थ्रेड को सिग्नल" प्रिंट करता है।

सेट विधि

AutoResetEvent सेट विधि ने अपने कार्य को आगे बढ़ाने के लिए प्रतीक्षा थ्रेड को संकेत भेजा। नीचे सेट विधि को कॉल करने का सिंटैक्स है।

autoResetEvent.Set();

ManualResetEvent मेमोरी में बूलियन चर बनाए रखता है। जब बूलियन वेरिएबल गलत होता है तो यह सभी थ्रेड्स को ब्लॉक कर देता है और जब बूलियन वेरिएबल सही होता है तो यह सभी थ्रेड को अनब्लॉक कर देता है।

जब हम एक ManualResetEvent को झटपट बंद करते हैं, तो हम इसे डिफ़ॉल्ट बूलियन मान के साथ आरंभ करते हैं।

ManualResetEvent manualResetEvent = new ManualResetEvent(false);

उपरोक्त कोड में, हम गलत मूल्य के साथ ManualResetEvent को इनिशियलाइज़ करते हैं, इसका मतलब है कि सभी थ्रेड्स जो WaitOne विधि को कॉल करते हैं, जब तक कि कुछ थ्रेड सेट () विधि को कॉल नहीं करते।

अगर हम सच्चे मूल्य के साथ ManualResetEvent को इनिशियलाइज़ करते हैं, तो WaitOne मेथड को कॉल करने वाले सभी थ्रेड आगे बढ़ने के लिए ब्लॉक और फ्री नहीं होंगे।

WaitOne विधि

यह विधि वर्तमान थ्रेड को ब्लॉक करती है और अन्य थ्रेड द्वारा सिग्नल की प्रतीक्षा करती है। अगर यह एक संकेत प्राप्त करता है तो यह सच हो जाता है और दूसरा गलत हो जाता है।

नीचे WaitOne विधि को कॉल करने का सिंटैक्स है।

manualResetEvent.WaitOne();

WaitOne विधि के दूसरे अधिभार में, हम सिग्नल के लिए वर्तमान थ्रेड प्रतीक्षा तक समय अंतराल निर्दिष्ट कर सकते हैं। यदि समय के भीतर, यह एक संकेत प्राप्त नहीं करता है यह गलत है और विधि की अगली पंक्ति में चला जाता है।

नीचे समय अंतराल के साथ WaitOne विधि को कॉल करने का सिंटैक्स है।

bool isSignalled = manualResetEvent.WaitOne(TimeSpan.FromSeconds(5));

हमने WaitOne विधि में 5 सेकंड निर्दिष्ट किए हैं। यदि मैन्युअलResetEvent ऑब्जेक्ट 5 सेकंड के बीच एक संकेत प्राप्त नहीं करता है, तो यह isSignalled चर को गलत पर सेट करता है।

विधि सेट करें

इस पद्धति का उपयोग सभी प्रतीक्षा धागों को संकेत भेजने के लिए किया जाता है। सेट () मेथड को सेट करेंResResetEvent ऑब्जेक्ट बूलियन वेरिएबल ट्रू। सभी वेटिंग थ्रेड अनब्लॉक हैं और आगे बढ़ते हैं।

नीचे कॉल सेट () विधि का वाक्यविन्यास है।

manualResetEvent.Set();

रीसेट विधि

एक बार जब हम सेट () विधि को ManualResetEvent ऑब्जेक्ट पर कॉल करते हैं, तो इसका बूलियन सही रहता है। मान रीसेट करने के लिए हम रीसेट () विधि का उपयोग कर सकते हैं। रीसेट विधि बूलियन मान को असत्य में बदल देती है।

नीचे रीसेट पद्धति को कॉल करने का सिंटैक्स है।

manualResetEvent.Reset();

यदि हम थ्रेड को कई बार सिग्नल भेजना चाहते हैं तो हमें सेट विधि को कॉल करने के तुरंत बाद रीसेट विधि को कॉल करना होगा।


7

हाँ। यह बिल्कुल सही है।

आप राज्य को इंगित करने के तरीके के रूप में ManualResetEvent देख सकते हैं। कुछ चालू (सेट) या बंद (रीसेट) है। कुछ अवधि के साथ एक घटना। उस स्थिति के होने की प्रतीक्षा कर रहा कोई भी धागा आगे बढ़ सकता है।

एक AutoResetEvent एक संकेत के लिए अधिक तुलनीय है। एक शॉट ने संकेत दिया कि कुछ हुआ है। बिना किसी अवधि के एक घटना। आमतौर पर लेकिन जरूरी नहीं कि जो "कुछ" हुआ हो वह छोटा हो और उसे एक ही धागे द्वारा नियंत्रित किया जाना चाहिए - इसलिए एकल धागे के बाद स्वत: रीसेट घटना का सेवन कर लेता है।


7

हाँ य़ह सही हैं।

आप इन दोनों के उपयोग से एक विचार प्राप्त कर सकते हैं।

यदि आपको यह बताने की आवश्यकता है कि आप कुछ काम और अन्य (थ्रेड्स) के साथ समाप्त हो गए हैं तो इसके लिए इंतजार करना अब आगे बढ़ सकता है, आपको मैन्युअल रूप से उपयोग करना चाहिए।

यदि आपको किसी भी संसाधन में पारस्परिक अनन्य उपयोग करने की आवश्यकता है, तो आपको AutoResetEvent का उपयोग करना चाहिए।


1

यदि आप AutoResetEvent और ManualResetEvent को समझना चाहते हैं, तो आपको थ्रेडिंग नहीं बल्कि व्यवधान समझने की जरूरत है!

.NET निम्न-स्तरीय प्रोग्रामिंग को सबसे दूर संभव बनाना चाहता है।

एक इंटरप्ट को निम्न-स्तरीय प्रोग्रामिंग में उपयोग किया जाता है जो एक सिग्नल के बराबर होता है जो कम से उच्च (या इसके विपरीत) हो गया। जब ऐसा होता है तो प्रोग्राम अपने सामान्य निष्पादन को बाधित करता है और निष्पादन पॉइंटर को उस फ़ंक्शन पर ले जाता है जो इस घटना को संभालता है ।

पहली बात यह है कि जब एक बाधा को रोकने के लिए अपने राज्य को रीसेट करना है, तो इस तरह से हार्डवेयर काम करता है:

  1. एक पिन एक सिग्नल से जुड़ा है और हार्डवेयर इसे बदलने के लिए सुनता है (सिग्नल में केवल दो राज्य हो सकते हैं)।
  2. यदि सिग्नल में बदलाव का मतलब है कि कुछ हुआ है और हार्डवेयर ने मेमोरी चर लगाया है राज्य में (और यह इस तरह से बना रहता है, भले ही सिग्नल फिर से बदल जाए)।
  3. कार्यक्रम सूचना है कि परिवर्तनशील राज्य को बदलता है और निष्पादन को एक हैंडलिंग फ़ंक्शन पर ले जाता है।
  4. यहां पहली बात यह है कि इस रुकावट को फिर से सुनने में सक्षम होने के लिए, इस मेमोरी चर को राज्य में नहीं होने के लिए रीसेट करना है।

यह मैनुअलResetEvent और AutoResetEvent के बीच अंतर है।
यदि कोई मैन्युअलResetEvent होता है और मैं इसे रीसेट नहीं करता हूं, तो अगली बार ऐसा होता है कि मैं इसे नहीं सुन पाऊंगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.