AutoResetEvent+与+ManualResetEvent区别

    技术2022-05-20  38

     

    在C#多线程编程中,这两个类几乎是不可或缺的,他们的用法/声明都很类似,那么区别在哪里了?

    Set方法将信号置为发送状态 Reset方法将信号置为不发送状态 WaitOne等待信号的发送

    其实,从名字就可以看出一点端倪  ,一个手动,一个自动,这个手动和自动实际指的是在Reset方法的处理上,如下面例子

    public AutoResetEvent autoevent=new AutoResetEvent(true);

    public ManualResetEvent manualevent=new ManualResetEvent(true);

    默认信号都处于发送状态,

    autoevent.WaitOne();

    manualevent.WaitOne();

    如果 某个线程调用上面该方法,则当信号处于发送状态时,该线程会得到信号,得以继续执行

    差别就在调用后,autoevent.WaitOne()每次只允许一个线程进入,当某个线程得到信号(也就是有其他线程调用

    了autoevent.Set()方法后)后,autoevent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只有继续等待.也就是说,autoevent一次只唤醒一个线程

    而manualevent则可以唤醒多个线程,因为当某个线程调用了set方法后,其他调用waitone的线程获得信号得以继续执行,而manualevent不会自动将信号置为不发送.也就是说,除非手工调用了manualevent.Reset().方法,则

    manualevent将一直保持有信号状态,manualevent也就可以同时唤醒多个线程继续执行

     

     

    1. Set() 方法  将事件状态设置为终止状态,允许一个或多个等待线程继续

                 对于Auto信号 Set 方法释放单个线程。如果没有等待线程,等待句柄将一直保持终止状态,直到某个线程尝试等待它,或者直到它Reset()  方法被调用。

                 对于Manual信号  调用 Set 方法将使等待句柄一直保持终止状态,直到它的 Reset 方法被调用。(也就是说等待这个信号的一个或多个 线路能继续运行,如果不调用Reset()就不终止)

     

    2. Reset()方法 将事件状态设置为非终止状态,导致线程阻止。

     

     

     关于ManualRestEvents 与AutoResetEvents 中代码,描述ManualResetEvents一次能换醒多个线程,而AutoResetEvents只能一次换醒一个,一个一个换醒,(一个运行后,AutoResetEvents会自己设置为不发送或都叫非终止状态

     

    public class Example {     // The EventWaitHandle used to demonstrate the difference     // between AutoReset and ManualReset synchronization events.     //     private static EventWaitHandle ewh;

        // A counter to make sure all threads are started and     // blocked before any are released. A Long is used to show     // the use of the 64-bit Interlocked methods.     //     private static long threadCount = 0;

        // An AutoReset event that allows the main thread to block     // until an exiting thread has decremented the count.     //     private static EventWaitHandle clearCount =         new EventWaitHandle(false, EventResetMode.AutoReset);

        [MTAThread]     public static void Main()     {         // Create an AutoReset EventWaitHandle.         //         ewh = new EventWaitHandle(false, EventResetMode.AutoReset);

            // Create and start five numbered threads. Use the         // ParameterizedThreadStart delegate, so the thread         // number can be passed as an argument to the Start         // method.         for (int i = 0; i <= 4; i++)         {             Thread t = new Thread(                 new ParameterizedThreadStart(ThreadProc)             );             t.Start(i);         }

            // Wait until all the threads have started and blocked.         // When multiple threads use a 64-bit value on a 32-bit         // system, you must access the value through the         // Interlocked class to guarantee thread safety.         //         while (Interlocked.Read(ref threadCount) < 5)         {             Thread.Sleep(500);         }

            // Release one thread each time the user presses ENTER,         // until all threads have been released.         //         while (Interlocked.Read(ref threadCount) > 0)         {             Console.WriteLine("Press ENTER to release a waiting thread.");             Console.ReadLine();

                // SignalAndWait signals the EventWaitHandle, which             // releases exactly one thread before resetting,             // because it was created with AutoReset mode.             // SignalAndWait then blocks on clearCount, to             // allow the signaled thread to decrement the count             // before looping again.             //             WaitHandle.SignalAndWait(ewh, clearCount);         }         Console.WriteLine();

            // Create a ManualReset EventWaitHandle.         //         ewh = new EventWaitHandle(false, EventResetMode.ManualReset);

            // Create and start five more numbered threads.         //         for(int i=0; i<=4; i++)         {             Thread t = new Thread(                 new ParameterizedThreadStart(ThreadProc)             );             t.Start(i);         }

            // Wait until all the threads have started and blocked.         //         while (Interlocked.Read(ref threadCount) < 5)         {             Thread.Sleep(500);         }

            // Because the EventWaitHandle was created with         // ManualReset mode, signaling it releases all the         // waiting threads.         //         Console.WriteLine("Press ENTER to release the waiting threads.");         Console.ReadLine();         ewh.Set();

            Console.ReadLine();             }

        public static void ThreadProc(object data)     {         int index = (int) data;

            Console.WriteLine("Thread {0} blocks.", data);         // Increment the count of blocked threads.         Interlocked.Increment(ref threadCount);

            // Wait on the EventWaitHandle.         ewh.WaitOne();

            Console.WriteLine("Thread {0} exits.", data);         // Decrement the count of blocked threads.         Interlocked.Decrement(ref threadCount);

            // After signaling ewh, the main thread blocks on         // clearCount until the signaled thread has         // decremented the count. Signal it now.         //         clearCount.Set();     } }

     

    结果图:

     

     

    转载:http://http://blog.csdn.net/tijichen/archive/2005/03/02/307531.aspx


    最新回复(0)