views:

335

answers:

2

I just downloaded the trial version of ANTS Performance Profiler from Red Gate and am investigating some of my team's code. Immediately I notice that there's a particular section of code that ANTS is reporting as eating up to 99% CPU time.

I am completely unfamiliar with ANTS or performance profiling in general (that is, aside from self-profiling using what I'm sure are extremely crude and frowned-upon methods such as double timeToComplete = (endTime - startTime).TotalSeconds), so I'm still fiddling around with the application and figuring out how it's used. But I did call the developer responsible for the code in question and his immediate reaction was "Yeah, that doesn't surprise me that it says that; but that code calls SignalAndWait [which I could see for myself, thanks to ANTS], which doesn't use any CPU, it just sits there waiting for something to do." He advised me to simply ignore that code and look for anything ELSE I could find.

My question: is it true that SignalAndWait requires NO CPU overhead (and if so, how is this possible?), and is it reasonable that a performance profiler would view it as taking up 99% CPU time? I find this particularly curious because, if it's at 99%, that would suggest that our application is often idle, wouldn't it? And yet its performance has become rather sluggish lately.

Like I said, I really am just a beginner when it comes to this tool, and I don't know anything about the WaitHandle class. So ANY information to help me to understand what's going on here would be appreciated.

+1  A: 

A WaitHandle does indeed put your Thread to sleep.

The added bonus is you can set timeouts on these Handles so that they can wake after a period of time.

You can also Signal the WaitHandle from another thread (eg. Application exit etc) and they immediately WakeUp.

I personally prefer a WaitHandle with a Short timeout over a Thread.Sleep with the same timeout, as when a Sleep is started it must return before you can resume operation, whilst a WaitHandle can be resumed immediately if required.

Paul Farry
A: 

I think you might have a serious bug in your code. EventWaitHandle has 2 semantics depending on its reset mode. When EventWaitHandle are in AutoReset mode, then all waiting threads are blocked until the event is signaled, once the event is signal, subsequent wait operations on it reset its state and the thread calling wait block again on it.

However, if the EventWaitHandle is in ManualReset Mode, it will remain signaled until you call Reset Manually on it, this means that if an EventWaitHandle is signaled and a thread is calling wait on it in a tight loop, this thread will not block until Reset is called manually on the event, so consider this hyphothetical scenario

EventWaitHandle h1, h2;
h1 = new EventWaitHandle(true, EventWaitHandle.ManualReset); // the event is already signaled.
h2 = new EventWaitHandle(false, EventWaitHandle.ManualReset);
while(true)
{
  WaitHandle.SignalAndWait(h2,h1);
}

the loop above will eat most of your CPU until some other thread calls h1.Reset(), which will make SignalAndWait blocks.

Hope this helps.

For more information, check out http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx

mfawzymkh