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 | One response 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