AutoResetEvent+與+ManualResetEvent區別

 

在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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章