Turn AutoResetEvent and understanding of the ManualResetEvent

First, the role

AutoResetEven t and ManualResetEvent can be used to control thread pause or continue, with three important methods: WaitOne , the Set and the Reset .

The official definition of these three methods are not well understood, what termination, non-termination, a mess. Here we come to a concept easy to understand instructions.

 

Second, the metaphor

If each thread compared to a car, then, AutoResetEvent and ManualResetEvent is a toll station on the road.

among them:

Reset  closed toll booths brakes closed to traffic (we go to intercept the vehicle fee ah);

WaitOne  lower toll wait for a vehicle to come (and charges);

Set     to open toll stations brake release (pay to let the past).

 

Third, the difference between the AutoResetEvent and ManualResetEvent

Since AutoResetEvent and ManualResetEvent all toll stations, then there is what is the difference between them?

As the name suggests, Auto automatically, Manual i.e. manually, the Reset shows a close analogy brakes above, i.e. the former is automatically closed brake, which brakes need to manually shut down.

Automatically turn off the brakes : the car after pay by, the brakes will automatically shut down, and then wait for the next car over pay. That is, each vehicle must go through so many steps: the resistance> Contributions> passage> brake closed

Close brakes manually : Open the rear brake, brake does not close automatically, if not manually turned off the brakes (ie call ManualResetEvent.Reset () method), then the vehicle will be a bumper by ......

 

So WaitOne charging operation depends on whether the brake closed ( the Reset ), if the brake is on, WaitOne fees desire can only come to nothing, toll stations exist in name only.

 

Fourth, the initial state and the ManualResetEvent AutoResetEvent

By providing AutoResetEvent and ManualResetEvent constructor initializes toll brake state:

Auto new new / ManualResetEvent (false) : brakes off by default;
new new Auto / ManualResetEvent (to true) :  brake enabled by default.

If the new new Auto / ManualResetEvent (to true) , that is turned on by default, then brakes, WaitOne did not make any sense, through the vehicle through.

Look at the code below:

Copy the code

        static EventWaitHandle _tollStation = new AutoResetEvent (true ); // default on brake 

        static void the Main (String [] args) 
        { 
            new new the Thread (Car1) .Start (); 
            the Console.ReadKey (); 
        } 

        static void Car1 () 
        { 
            _tollStation .WaitOne (); // because the brakes on by default, WaitOne meaningless, does not prevent the vehicle front line 
            Console.WriteLine ( "! alas brakes are open, I come!"); 
        }

Copy the code

The print run:

Alas! Brakes are open, I come!

If the new AutoResetEvent (true)  instead new new AutoResetEvent (flase) , namely brake is off by default, it will not print any value that vehicles can not pass.

How can you pass it? It must be called in the main thread Set method, which can be opened by the brakes.

Code:

 

Copy the code

        static EventWaitHandle _tollStation = new AutoResetEvent (false ); // Close brake default 

        static void the Main (String [] args) 
        { 
            new new the Thread (Car1) .Start (); 
            _tollStation.Set (); // open brake 
            Console.ReadKey (); 
        } 

        static void Car1 () 
        { 
            _tollStation.WaitOne (); // wait turned brakes, namely _event.Set (); 
            Console.WriteLine ( "brakes on, I'm coming!"); 
        }

Copy the code

The print run:

Brakes on, I come!

Code is very clear, is not explained, in short, is the brakes off by default, only open the brake (call the Set method), the vehicle can pass.

 

Fifth, with the characteristic code illustrates the AutoResetEvent

Code:

Copy the code

        static EventWaitHandle _tollStation = new AutoResetEvent (false ); // Close brake default 

        static void the Main (String [] args) 
        { 
            new new the Thread (Car1) .Start (); // vehicle. 1 
            new new the Thread (Car2) .Start (); // vehicle 2 
            _tollStation.Set (); 
            the Console.ReadKey (); 
        } 

        static void Car1 () 
        { 
            _tollStation.WaitOne (); // wait brakes open, i.e. _tollStation.Set (); 
            Console.WriteLine ( "vehicle 1, passed "); 
        } 

        static void Car2 () 
        { 
            _tollStation.WaitOne (); 
            Console.WriteLine (" vehicle 2, passed ");.! 
        }

Copy the code

The print run:

Vehicle 1, passed.

While the vehicle 1 and 2 vehicles are running, but only 1 vehicle passed.

Since _tollStation.Set () runs only once, i.e., after the vehicle 1 through the brake is immediately turned off, causing the vehicle 2 has not passed.

Unless, in the vehicle 1 once again by calling _tollStation.Set () , opens the brakes, the vehicle again by 2 to:

Copy the code

        static EventWaitHandle _tollStation = new AutoResetEvent (false ); // Close brake default 

        static void the Main (String [] args) 
        { 
            new new the Thread (Car1) .Start (); // vehicle. 1 
            new new the Thread (Car2) .Start (); // vehicle 2 
            _tollStation.Set (); // open the brake, so that the vehicle 1 by 
            the Console.ReadKey (); 
        } 

        static void Car1 () 
        { 
            _tollStation.WaitOne (); // wait brakes open, i.e. _tollStation. SET (); 
            Console.WriteLine ( "vehicle 1, passed."); 
            _tollStation.Set (); // open again once the brakes, so that the vehicle 2 through 
        } 

        static void Car2 () 
        { 
            _tollStation.WaitOne ();  
            Console .WriteLine ( "vehicle 2 passed.");
        }

Copy the code

The print run:

Vehicle 1, passed.

2 vehicles, passed.

Each call is the Set , only one thread will continue. In other words, how many threads How many times must call the Set , all threads will continue.

It also shows, the AutoResetEvent typical form of queue operations.

 

Six, with the characteristic code illustrates the ManualResetEvent

On a code block, _tollStation.Set () is called twice, two cars passed.

So, is there any way to call only once _tollStation.Set () let two or more cars passed it?

The answer is that the AutoResetEvent changed ManualResetEvent :

Copy the code

        static EventWaitHandle _tollStation = new ManualResetEvent (false ); // to ManualResetEvent, brake off by default 

        static void the Main (String [] args) 
        { 
            new new the Thread (Car1) .Start (); // vehicle. 1 
            new new the Thread (Car2). Start (); // vehicle 2 
            _tollStation.Set (); // open the brake, the vehicle will pass all 
            the Console.ReadKey (); 
        } 

        static void Car1 () 
        { 
            _tollStation.WaitOne (); // wait brake open, i.e. _tollStation.Set (); 
            Console.WriteLine ( "vehicle 1, passed."); 
            //_tollStation.Set();// no longer needed here 
        } 

        static void Car2 () 
        { 
            _tollStation.WaitOne ();
            Console.WriteLine ( "vehicle 2 passed."); 
        }

Copy the code

 

The print run:

Vehicle 1, passed.

2 vehicles, passed.

This is a very good description, ManualResetEvent does not automatically turn off this feature after turning brakes. So called once _tollStation.Set () , all vehicles will pass.

If you turn off the brakes manually at some point, the back of the vehicle will not pass. As the following code:

Copy the code

static EventWaitHandle _tollStation = new ManualResetEvent (false ); // to ManualResetEvent, brake off by default 

        static void the Main (String [] args) 
        { 
            new new the Thread (Car1) .Start (); // vehicle. 1 
            new new the Thread (Car2). the Start (); // vehicle 2 

            _tollStation.Set (); // open brake, release 
            Timer timer = new Timer (CloseDoor, null, 0, 2000); // 2 seconds after the brakes off 

            the Console.ReadKey (); 
        } 

        static void Car1 () 
        { 
            _tollStation.WaitOne (); // wait brakes open, i.e. _tollStation.Set (); 
            Console.WriteLine ( "vehicle 1, passed."); 
        } 

        static void Car2 () 
        { 
            the Thread .Sleep (3000); // sleep three seconds
            _tollStation.WaitOne (); // if the brake has been turned off wake 
            Console.WriteLine ( "vehicle 2 passed."); // 2 so that the vehicle will not be through 
        } 

        /// <Summary> 
        /// brake off after 2 seconds 
        /// </ Summary> 
        static void CloseDoor (Object O) 
        { 
            _tollStation.Reset (); // Close brake 
        }

Copy the code

The print run:

Vehicle 1, passed.

2 and the vehicle will not pass, because when the vehicle 2 wake up before the brake is turned off 2 seconds.

 

Seven summary

1, it seems, ManualResetEvent more free and open. If AutoResetEvent seen as only single-pass single-plank bridge, then ManualResetEvent like a gate, can all of a sudden influx of millions of soldiers, of course, you can also close the gates at any time, so that people could not come back.

2、AutoResetEvent.Set() = ManualResetEvent.Set() + ManualResetEvent.Reset();

3, if the shared resources to allow only a case where the thread used alone, may select the AutoResetEvent ; if the shared resource allows multiple threads simultaneously, you can select the ManualResetEvent .

4, if you want to control multiple threads pause, resume, you can choose ManualResetEvent .

Guess you like

Origin blog.csdn.net/wlanye/article/details/90602104