.NET এ ম্যানুয়ালসেটসেন্ট এবং অটোসেটসেন্টের মধ্যে পার্থক্য কী?


532

আমি এটিতে ডকুমেন্টেশন পড়েছি এবং আমার মনে হয় আমি বুঝতে পেরেছি। AutoResetEventকোডটি যখন পাস হয় তখন একটি পুনরায় সেট করে event.WaitOne(), তবে একটি ManualResetEventতা করে না।

এটা কি সঠিক?


2
এই এভ পার্থক্য বুঝতে সহায়তা করবে
বিনোদ শ্রীবাস্তব

উত্তর:


919

হ্যাঁ. এটি টোলবুথ এবং একটি দরজার পার্থক্যের মতো। ManualResetEventদরজা, যা বন্ধ হয়ে (রিসেট) ম্যানুয়ালি প্রয়োজন। AutoResetEventএকটি tollbooth, এক গাড়ী যেতে সক্ষম হবেন আগে পরের এক মাধ্যমে পেতে পারেন স্বয়ংক্রিয়ভাবে বন্ধ।


166
এটি একটি দুর্দান্ত উপমা।
শে

আরও খারাপ, ওয়েটওনে এআরই সেট করা থেকে বেশিক্ষণ অপেক্ষা করবেন না, বা এর মধ্যে এটি পুনরায় সেট করা হবে। সেই সাথে অনেকগুলি পরিত্যক্ত থ্রেড ছিল।
অলিভার ফ্রেডরিখ

24
বা একটি দরজা এবং একটি ঘুরে বেড়ানোর মতো।
কনস্টান্টিন

9
ওহ, এ কারণেই তারা তাদের নামকরণ করেছে।
অরলেন বেলার

1
: @DanGoldstein ওয়েল, এই যেহেতু বন্ধ করা হয় না এবং ক্ষেত্রে অন্য কেউ এটা ব্যবহার করতে চান msdn.microsoft.com/en-us/library/...
ফিল এন DeBlanc

124

শুধু কল্পনা AutoResetEvent, executes WaitOne()এবং Reset()একটি একক পারমাণবিক অপারেশন হিসাবে।


16
আপনি যদি ম্যানুয়ালসেটসেন্ট ইভেন্টে ওয়েটওনকে একক পারমাণবিক ক্রিয়াকলাপ হিসাবে চালিত করেন এবং সেট করেন তবে এটি অটোসেটসেন্টের থেকে আলাদা কিছু করতে পারে Ex ম্যানুয়ালসেটসেন্ট সমস্ত ওয়েটিং থ্রেড একই সাথে প্রকাশ করে, যেখানে অটোসেটসেন্ট হিসাবে কেবলমাত্র একটি অপেক্ষার থ্রেড প্রকাশের গ্যারান্টি রয়েছে।
মার্টিন ব্রাউন

55

সংক্ষিপ্ত উত্তর হল হ্যাঁ. সর্বাধিক গুরুত্বপূর্ণ পার্থক্যটি হ'ল একটি অটোসেটসেন্ট কেবলমাত্র একটি একক অপেক্ষার থ্রেড চালিয়ে যেতে দেয়। অন্যদিকে একটি ম্যানুয়ালসেটভেনড থ্রেডগুলি একই সাথে একত্রে চালিয়ে যাওয়ার অনুমতি দেবে, যতক্ষণ না আপনি এটি বন্ধ করতে বলেন (এটি পুনরায় সেট করুন)।


36

সি # 3.0 সংক্ষেপে বইটি নেওয়া হয়েছে, জোসেফ আলবাহারি রচিত

সি # তে থ্রেডিং - ফ্রি ই-বুক

একটি ম্যানুয়ালসেটসেন্ট হ'ল অটোসেটসেন্টে একটি ভিন্নতা। এটি পৃথক হয় যে এটি একটি ওয়েটওন কলের মাধ্যমে থ্রেডটি দেওয়ার পরে স্বয়ংক্রিয়ভাবে পুনরায় সেট হয় না, এবং গেটের মতো ফাংশন: কলিং সেটটি গেটটি খোলে, গেটে ওয়েটওনের যে কোনও সংখ্যক থ্রেডের মাধ্যমে প্রবেশ করে; রিসেট কলিং গেটটি বন্ধ করে দেয় যার ফলে সম্ভাব্যভাবে ওয়েটারগুলির একটি সারি তার পরবর্তী খোলা না হওয়া পর্যন্ত জমা হতে পারে।

"স্পিন-স্লিপিং" - বারবার পতাকাটি পরীক্ষা করা, এবং তারপরে স্বল্প সময়ের জন্য ঘুমানোর সাথে সাথে কেউ এই কার্যকারিতাটি বুলিয়ান "গেটঅপেন" ক্ষেত্রের (উদ্বোধনী কীওয়ার্ড দিয়ে ঘোষিত) সাথে অনুকরণ করতে পারে।

ম্যানুয়ালসেটসেন্টস কখনও কখনও নির্দিষ্ট ক্রিয়াকলাপ সম্পূর্ণ, বা কোনও থ্রেডের সম্পূর্ণ আরম্ভ হয় এবং কাজ সম্পাদনের জন্য প্রস্তুত হয় তা সংকেত দিতে ব্যবহৃত হয়।


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();
}

পারমাণবিক অপারেশন হিসাবে


এটি কেবল ধারণাগতভাবে সঠিক, তবে ব্যবহারিকভাবে নয়। ওয়েটওন এবং রিসেটের মধ্যে একটি প্রসঙ্গ সুইচ ঘটতে পারে; এটি সূক্ষ্ম বাগগুলি হতে পারে।
hofingerandi

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);
        }
    }

}

অটো রিসেট ইভেন্ট আউটপুট


এটি সমস্ত বোঝার সর্বোত্তম উপায় ছিল, কোডটি অনুলিপি করে
রেখেছিলেন

8

অটোসেটসেন্ট স্মৃতিতে একটি বুলিয়ান পরিবর্তনশীল বজায় রাখে। যদি বুলিয়ান ভেরিয়েবলটি মিথ্যা হয় তবে এটি থ্রেডটিকে ব্লক করে এবং বুলিয়ান ভেরিয়েবলটি সত্য হলে এটি থ্রেডটি অবরোধ মুক্ত করে।

যখন আমরা একটি অটোসেটসেন্ট অবজেক্টটি ইনস্ট্যান্ট করি, আমরা কনস্ট্রাক্টরে বুলিয়ান মানের ডিফল্ট মানটি পাস করি। নীচে একটি অটোসেটসেন্ট অবজেক্টটি ইনস্ট্যান্ট করার সিনট্যাক্স রয়েছে।

AutoResetEvent autoResetEvent = new AutoResetEvent(false);

অপেক্ষা করুন পদ্ধতি

এই পদ্ধতিটি বর্তমান থ্রেডকে অবরুদ্ধ করে এবং অন্যান্য থ্রেড দ্বারা সিগন্যালের জন্য অপেক্ষা করে। ওয়েটওন পদ্ধতিটি বর্তমান থ্রেডকে স্লিপ থ্রেডের স্থানে রাখে। অপেক্ষারত পদ্ধতিটি সত্যটি প্রত্যাশা করে যদি এটি সংকেতটি গ্রহণ করে অন্য কোনওটি মিথ্যা করে।

autoResetEvent.WaitOne();

ওয়েটওন পদ্ধতির দ্বিতীয় ওভারলোড নির্দিষ্ট সেকেন্ডের জন্য অপেক্ষা করুন। এটি কোনও সিগন্যাল থ্রেড না পেলে এটির কাজ চালিয়ে যায়।

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

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

আর্গুমেন্ট হিসাবে 2 সেকেন্ড পেরিয়ে আমরা ওয়েটওন পদ্ধতিটি কল করি। লুপের মধ্যে, এটি 2 সেকেন্ডের জন্য সিগন্যালের জন্য অপেক্ষা করে তারপরে এটির কাজ চালিয়ে যায়। থ্রেডটি সিগন্যাল পেলে অপেক্ষা করুন সত্য প্রত্যাবর্তন করে এবং লুপটি প্রস্থান করে এবং "থ্রেডটি পেয়ে গেল সিগন্যাল" print

সেট পদ্ধতি

অটোসেটসেন্ট সেট পদ্ধতিটি এর কাজ এগিয়ে যাওয়ার জন্য ওয়েটিং থ্রেডে সংকেত পাঠিয়েছে। নীচে কল পদ্ধতি সেট কল করার সিনট্যাক্সটি রয়েছে।

autoResetEvent.Set();

ম্যানুয়ালসেটভেন্ট মেমরিতে একটি বুলিয়ান পরিবর্তনশীল বজায় রাখে। বুলিয়ান ভেরিয়েবলটি মিথ্যা হলে এটি সমস্ত থ্রেডকে ব্লক করে এবং বুলিয়ান ভেরিয়েবলটি সত্য হলে এটি সমস্ত থ্রেডকে অবরোধ মুক্ত করে।

আমরা যখন কোনও ম্যানুয়ালসেটসেন্টটি ইনস্ট্যান্ট করি তখন আমরা এটি ডিফল্ট বুলিয়ান মান দিয়ে শুরু করি।

ManualResetEvent manualResetEvent = new ManualResetEvent(false);

উপরের কোডে, আমরা ম্যানুয়ালসেটসেন্টকে মিথ্যা মান দিয়ে আরম্ভ করব, এর অর্থ কিছু থ্রেড যা ওয়েটওন পদ্ধতি কল করে সেগুলি ব্লক হবে যতক্ষণ না কিছু থ্রেড সেট () পদ্ধতি কল করে।

যদি আমরা ম্যানুয়ালসেটসেন্টকে সত্য মানের সাথে আরম্ভ করি, তবে সমস্ত থ্রেড যা ওয়েটওন পদ্ধতিটিকে কল করে তা অবরুদ্ধ করবে না এবং আরও এগিয়ে যেতে নিরুক্ত হবে।

অপেক্ষা করুন পদ্ধতি

এই পদ্ধতিটি বর্তমান থ্রেডকে অবরুদ্ধ করে এবং অন্যান্য থ্রেড দ্বারা সিগন্যালের জন্য অপেক্ষা করে। এটি সত্য প্রত্যাবর্তন করে যদি এটির সিগন্যাল পাওয়া অন্য কোনওটি মিথ্যা করে returns

নীচে ওয়েটওন পদ্ধতিতে কল করার বাক্য গঠন রয়েছে।

manualResetEvent.WaitOne();

ওয়েটওন পদ্ধতির দ্বিতীয় ওভারলোডে, বর্তমান থ্রেড সিগন্যালের অপেক্ষা না হওয়া পর্যন্ত আমরা সময়ের ব্যবধানটি নির্দিষ্ট করতে পারি। যদি অভ্যন্তরীণ সময়ের মধ্যে, এটি একটি সংকেত না পেয়ে এটি মিথ্যা প্রত্যাবর্তন করে এবং পদ্ধতির পরবর্তী লাইনে চলে যায়।

নীচে সময়ের ব্যবধানের সাথে ওয়েটওন পদ্ধতিতে কল করার বাক্য গঠন রয়েছে।

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

ওয়েটওন পদ্ধতিতে আমরা 5 সেকেন্ড নির্দিষ্ট করেছি। যদি ম্যানুয়ালসেটসেন্ট অবজেক্টটি 5 সেকেন্ডের মধ্যে একটি সংকেত না পেয়ে থাকে তবে এটি ইসসাইনাল ভেরিয়েবলটিকে মিথ্যা হিসাবে সেট করে।

পদ্ধতি সেট করুন

এই পদ্ধতিটি সমস্ত অপেক্ষার থ্রেডে সংকেত প্রেরণের জন্য ব্যবহৃত হয়। সেট () পদ্ধতিটি ম্যানুয়ালসেটইভেন্ট অবজেক্ট বুলিয়ান ভেরিয়েবলকে সত্য হিসাবে সেট করে। সমস্ত অপেক্ষার থ্রেডগুলি অবরুদ্ধ করা আছে এবং আরও এগিয়ে চলেছে।

নীচে কল (সেট) পদ্ধতি কল করার সিনট্যাক্স রয়েছে।

manualResetEvent.Set();

পুনরায় সেট করার পদ্ধতি

একবার আমরা ম্যানুয়ালসেটইভেন্ট অবজেক্টে সেট () পদ্ধতিটি কল করি, এর বুলিয়ান সত্য থাকে। মানটি পুনরায় সেট করতে আমরা রিসেট () পদ্ধতিটি ব্যবহার করতে পারি। পুনরায় সেট করার পদ্ধতিটি বুলেয়নের মানটিকে মিথ্যাতে পরিবর্তন করে।

নীচে কলিং রিসেট পদ্ধতিটির বাক্য গঠন রয়েছে।

manualResetEvent.Reset();

আমরা একাধিক বার থ্রেডে সংকেত পাঠাতে চাইলে সেট পদ্ধতিতে কল করার পরে আমাদের অবিলম্বে রিসেট পদ্ধতিটি কল করতে হবে।


7

হ্যাঁ. এটি একেবারে সঠিক।

আপনি রাষ্ট্রকে নির্দেশ করার উপায় হিসাবে ম্যানুয়ালসেটসেন্টকে দেখতে পেতেন। কিছু চালু (সেট) বা অফ (রিসেট)। কিছু সময়কাল সহ একটি ঘটনা। সেই অবস্থা হওয়ার জন্য অপেক্ষা করা কোনও থ্রেড এগিয়ে যেতে পারে।

একটি অটোসেটসেন্ট একটি সংকেতের সাথে তুলনামূলক বেশি। একটি ঘটনার ইঙ্গিত যে কিছু ঘটেছে। কোনও সময়কাল ছাড়া ঘটনা occ সাধারণত তবে অগত্যা যে "কিছু" ঘটেছে তা ছোট এবং এটি একটি একক থ্রেড দ্বারা পরিচালনা করা দরকার - তাই কোনও থ্রেডের পরে স্বয়ংক্রিয় পুনরায় সেটটি ইভেন্টটি গ্রাস করেছে।


7

হ্যা, তা ঠিক.

আপনি এই দুটি ব্যবহার করে একটি ধারণা পেতে পারেন।

আপনার যদি কিছু বলার দরকার হয় যে আপনি কিছু কাজ শেষ করেছেন এবং এটির জন্য অপেক্ষা করা অন্যান্য (থ্রেড) এখন এগিয়ে যেতে পারে তবে আপনার ম্যানুয়ালসেটসেন্ট ব্যবহার করা উচিত।

আপনার যদি কোনও সংস্থানটিতে পারস্পরিক একচেটিয়া অ্যাক্সেসের প্রয়োজন হয় তবে আপনার অটোসেটসেন্ট ব্যবহার করা উচিত।


1

আপনি যদি অটোসেটসেন্ট এবং ম্যানুয়ালসেটসেন্ট বুঝতে চান তবে আপনার থ্রেডিং নয় বরং বিঘ্ন বুঝতে হবে!

.NET সর্বনিম্নতম নিম্ন স্তরের প্রোগ্রামিং আপ করতে চায়।

একটি বাধা হ'ল নিম্ন-স্তরের প্রোগ্রামিংয়ে ব্যবহৃত এমন একটি সংকেতের সমান যা নিম্ন থেকে উচ্চ হয়ে যায় (বা বিপরীতমুখী)। এটি যখন ঘটে তখন প্রোগ্রামটি তার সাধারণ সম্পাদনকে ব্যাহত করে এবং এই ইভেন্টটি পরিচালনা করে এমন ক্রিয়ায় এক্সিকিউশন পয়েন্টারটি সরিয়ে দেয় ।

একটি বিঘ্নিত হ্যাপেনডের প্রথম কাজটি হ'ল তার স্থিতি পুনরায় সেট করা , কারণ হার্ডওয়্যার এইভাবে কাজ করে:

  1. একটি পিন একটি সিগন্যালের সাথে সংযুক্ত থাকে এবং হার্ডওয়্যার এটি পরিবর্তনের জন্য শোনায় (সিগন্যালে কেবল দুটি স্থিতি থাকতে পারে)।
  2. যদি সিগন্যাল পরিবর্তিত হয় মানে কিছু ঘটেছিল এবং হার্ডওয়্যার একটি মেমরি ভেরিয়েবল রাখে রাষ্ট্রের কাছে রাখে (এবং এটি আবার সিগন্যাল পরিবর্তিত হয়েও এমন থাকে)।
  3. প্রোগ্রামটি লক্ষ্য করে যে পরিবর্তনশীল পরিবর্তনগুলি জানিয়েছে এবং কার্যকরকরণটিকে একটি হ্যান্ডলিং ফাংশনে স্থানান্তরিত করে।
  4. এখানে প্রথমে করণীয়, আবার এই বাধাপ্রবণটি শুনতে সক্ষম হ'ল, এই স্মৃতি পরিবর্তনশীলটিকে রাষ্ট্রের সাথে পুনরায় সেট করা হয়নি happened

এটি ম্যানুয়ালসেটসেন্ট এবং অটোসেটসেন্টের মধ্যে পার্থক্য।
যদি কোনও ম্যানুয়ালসেটসেন্ট হয় এবং আমি এটি পুনরায় সেট না করি তবে পরবর্তী সময় এটি ঘটলে আমি এটি শুনতে সক্ষম হব না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.