AutoResetEvent vs ManualResetEvent: beware!

Julien on Apr 7th 2008

I did load testing last week on the component I am developing and found out that the performances were just miserable... It was barely capable of handling 60 messages per seconds which was: 1) bad and 2) surprising! (Basically it's doing some kind of real-time caching/transformation/redirection of messages).

I then spent 5mins in dotrace trying to get a picture of what was going on. I found that in the thread that is monitoring the queue and sending messages, I had used an instance of ManualResetEvent instead of AutoResetEvent.

If you never used them, these 2 classes allow you to send signals between 2 threads. That way, the "monitor" thread is not wasting any resources until it's notified by the other thread that there is something in the queue. For instance, Thread 1 will wait for a queue to be filled with something like that:

  1.  
  2. private AutoResetEvent _mySignal = new AutoResetEvent(false);
  3.  
  4. private void MonitorQueue()
  5. {
  6. while(!monitorQueue)
  7. {
  8. _mySignal.WaitOne();
  9. GetItemsInTheQueueAndDoStuff();
  10. }
  11. }

And thread 2 will inject data in the queue:

  1.  
  2. public void EnqueueItem(Item myItem)
  3. {
  4. InsertInQueue(myItem);
  5. _mySignal.Set();
  6. }
  7.  

As I said, my problem is that I used a ManualResetEvent instead of an AutoResetEvent. These 2 classes are almost the same except that when you use ManualResetEvent, you need to reset the signal manually with mySignal.Reset();. In my case, instead of blocking on mySignal.WaitOne(); the code was constantly looping and using a lot of CPU!

I fixed it and reran the load testing: now I'm at 5000 messages per seconds at 40% CPU. Much better!

Filed in .NET | 4 responses so far

4 Responses to “AutoResetEvent vs ManualResetEvent: beware!”

  1. Guimasun Jun 30th 2008 at 03:33 pm 1

    The same happened to me. I was using a AutoResentEvent to sinalize thread termination, but sometimes the condition had been tested inside the thread loop which resets the event, so the while condition would never end.
    Cheers

  2. Anonymous Sep 18th 2009 at 02:31 pm 2

    Yes u r right.. but there is one more problem here in AutoresetEvent’s
    Set Method.. It has to be called when it is needed. if not again u will get into trouble.

  3. Anonymous Sep 18th 2009 at 02:33 pm 3

    If AutoresetEvent’s Set is Called when it is not required, then there is no use of Waitone in the thread.. Beaware of it folks !!!

  4. ???????? ???? Jan 6th 2010 at 04:07 pm 4

    Just imagine that the AutoResetEvent executes WaitOne() and Reset() as a single atomic operation.
    thanks for the great article!

Trackback URI | Comments RSS

Leave a Reply