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:
private void MonitorQueue() { while(!monitorQueue) { _mySignal.WaitOne(); GetItemsInTheQueueAndDoStuff(); } }
And thread 2 will inject data in the queue:
public void EnqueueItem(Item myItem) { InsertInQueue(myItem); _mySignal.Set(); }
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 | 8 responses so far
The .Net Frog is also available in french at:
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
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.
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 !!!
???????? ???? 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!
Rick O'Shay Aug 19th 2010 at 10:47 pm 5
So, AutoResetEvent automatically resets while ManualResetEvent requires a manual reset. Reminds me of the time I scaled myself drinking what I thought was a cool drink of water. Turns out the tap labeled “hot” had hot water, I should have used the tap labeled “cold”.
Siva Koganti Dec 15th 2010 at 08:05 pm 6
Very good point elevated. Thanks!
sandeep Jul 20th 2011 at 08:53 pm 7
Well the name itself say.. AutoReset and ManualReset…
josef Aug 3rd 2011 at 07:16 pm 8
Hi
one more important difference to mark:
An autoreset event can only unblock one waitfor…object call. As the event will be reset by the first waitfor..object. Other waitfor…object loops will NOT unblock!
The manual reset event unblocks ALL waiting calls of waitfor…objects! The sender should then reset the event automatically.
regards
Josef