开发者

autoresetevent and manualresetevent

using System;
using System.Threading;

public class Example
{
    // mre is used to block and release threads manually. It is
    // created in the unsignaled state.
    private static ManualResetEvent mre = new ManualResetEvent(false);

    static void Main()
    {
        Console.WriteLine("\nStart 3 named threads that block on a ManualResetEvent:\n");

        for(int i = 0; i <= 2; i++)
        {
            Thread t = new Thread(ThreadProc);
            t.Name = "Thread_" + i;
            t.Start();
        }

        Thread.Sleep(500);
        Console.WriteLine("\nWhen all three threads have started, press Enter to call Set()" +
                          "\nto release all the threads.\n");
        Console.ReadLine();

        mre.Set();

        Thread.Sleep(500);
        Console.WriteLine("\nWhen a ManualResetEvent is signaled, threads that call WaitOne()" +
                          "\ndo not block. Press Enter to show this.\n");
        Console.ReadLine();

        for(int i = 3; i <= 4; i++)
        {
            Thread t = new Thread(ThreadProc);
            t.Name = "Thread_" + i;
            t.Start();
        }

        Thread.Sleep(500);
        Console.WriteLine("\nPress Enter to call Reset(), so that threads once again block" +
                          "\nwhen they call WaitOne().\n");
        Console.ReadLine();

        mre.Reset();

        // Start a thread that waits on the ManualResetEvent.
        Thread t5 = new Thread(ThreadProc);
        t5.Name = "Thread_5";
        t5.Start();

        Thread.Sleep(500);
        Console.WriteLine("\nPress Enter to call Set() and conclude the demo.");
        Console.ReadLine();

        mre.Set();

        // If you run this example in Visual Studio, uncomment the following line:
        //Console.ReadLine();
    }

    //thread entry point
    private static void ThreadProc()
    {
        string name = Thread.CurrentThread.Name;

        Console.WriteLine(name + " starts and cal开发者_如何学编程ls mre.WaitOne()");
        //wait untill signaled   
        mre.WaitOne();

        Console.WriteLine(name + " ends.");
    }
}

I wrote the example to understand autoresetevent and manualresetevent. But was not clear when we have to use Autoresetevent and manualresetevent synchornization? Above is the example for this. Please provide the real world scenario where we can use the event based sync.


There are a few places where this sort of thing is used. Personally I usually prefer Monitor.Wait/Pulse, but there are times when {Manual/Auto}ResetEvent is more useful - particularly where you want to be able to wait on multiple handles.

The two most obvious cases where I've seen this used are:

  • Producer/consumer queues: when the queue is empty, the consumer will wait on a monitor or wait handle. The producer will then pulse/set the monitor/handle when it's added an item, to wake up the consumer so it knows it has work to do.
  • Waking up a "sleeping" thread to let it know that it can exit: it's not unusual to have a while(!ShouldStop) { Work(); Wait(10000); } sort of loop; the "stopping" thread can again make the waiting thread wake up notice that the "stop" flag has been set

These are quite similar scenarios of course, and no doubt there are more - but those are the ones I've seen most often.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜