简体   繁体   中英

Why the outputs of my code is difference when using AutoResetEvent and ManualResetEvent in C#

I'm trying to understand the difference between AutoResetEvent and ManualResetEvent. Right now I understand that the AutoResetEvent lets each thread in a group of threads to do their works one by one. For instance, you have only one printer and you have two print tasks, you want print task 1 to finish before print task 2 start. In this situation, you will want to use AutoResetEvent. A ManualResetEvent is useful if you want to wake up a bunch of threads with a single event.

Right now I'm trying to use the following code snippet to understand how they work.

    static AutoResetEvent resetEvent = new AutoResetEvent(false);
    static void Main(string[] args)
    {
        Task task = Task.Run(() =>
        {
            GetDataFromServer(1);
        });

        Task.Run(() =>
        {
            GetDataFromServer(2);
        });


        //Send first signal to get first set of data from server 1 and server 2
        resetEvent.Set();
        //manualResetEvent.Reset();

        Thread.Sleep(TimeSpan.FromSeconds(2));
        //Send second signal to get second set of data from server 1 and server 2
        resetEvent.Set();

        Console.ReadLine();
    }

    static void GetDataFromServer(int serverNumber)
    {
        //Calling any webservice to get data
        Console.WriteLine("I get first data from server" + serverNumber);
        resetEvent.WaitOne();

        Thread.Sleep(TimeSpan.FromSeconds(2));
        Console.WriteLine("I get second data from server" + serverNumber);

        resetEvent.WaitOne();
        Console.WriteLine("All the data collected from server" + serverNumber);
    }

When I use the ManualResetEvent, it gives me the following output:

I get first data from server1

I get first data from server2

I get second data from server1

All the data collected from server1

I get second data from server2

All the data collected from server2

If I change the ManualResetEvent to AutoResetEvent, I get different output and the "All the data collected from server" never print out:

I get first data from server1

I get first data from server2

I get second data from server1

I get second data from server2

Seems like I still not fully understand how they work.

Question:

  1. Why they have different outputs and the "All the data collected from server" statement never print out when I use the AutoResetEvent? I call the Set() method to signal threads that they can perform their tasks.

  2. How come when I use the ManualResetEvent without calling the reset() and the output is the same as using it with the reset()?

  3. How can I change the code snippet to make it have the same output when using AutoResetEvent and ManualResetEvent?

Brief answers to your questions:

  1. AutoResetEvent resets automatically after it lets one thread through. In the code above, you are calling WaitOne() four times, so you would need to have four corresponding Set() calls. That's why you aren't seeing the last statements print; the threads are waiting for the signal.

  2. A manual reset event must be manually reset before it will begin blocking threads. The Set method releases all waiting threads, then there is then a race to finish before Reset is called. If those threads actually finish before Reset , your results will be as indicated.

  3. You cannot guarantee behavior will be the same regardless which one is used. The two have different behaviors, so substituting one for the other will yield different behavior at least some of the time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM