我刚刚下载了ANTS Performance Profiler from Red Gate的试用版,正在调查我团队的一些代码。我立即注意到ANTS报告的特定部分代码占用了高达99%的CPU时间。
我完全不熟悉ANTS或性能分析(也就是说,除了使用我确定非常粗糙和皱眉的方法(例如double timeToComplete = (endTime - startTime).TotalSeconds
)进行自我剖析外,所以我是仍在摆弄应用程序并弄清楚它是如何使用的。但我确实打电话给开发人员负责有问题的代码,他的立即反应是“是的,这并不让我感到惊讶,但是那个代码调用了SignalAndWait [我自己可以看到,感谢ANTS],它没有使用任何CPU,只是坐在那里等待一些事情要做。“他建议我简单地忽略那些代码并寻找我能找到的任何东西。
我的问题:SignalAndWait是否需要没有CPU开销(如果是这样,这怎么可能?),并且性能分析器将其视为占用99%的CPU时间是否合理?我发现这特别好奇,因为如果它是99%,那表明我们的应用程序通常是空闲的,不是吗?然而,它的表现最近变得相当迟缓。
就像我说的那样,对于这个工具我真的只是一个初学者,我对WaitHandle类一无所知。因此,有任何信息可以帮助我理解这里发生的事情。
答案 0 :(得分:1)
WaitHandle确实让你的线程处于睡眠状态。
额外的好处是你可以设置这些手柄的超时时间,以便他们可以在一段时间后醒来。
您也可以从另一个线程(例如,应用程序退出等)发出WaitHandle信号,然后立即唤醒它们。
我个人更喜欢具有相同超时的Thread.Sleep短暂超时的WaitHandle,就像启动睡眠时必须返回才能恢复操作,而WaitHandle可以恢复如果需要,立即。
答案 1 :(得分:0)
我认为您的代码中可能存在严重错误。 EventWaitHandle具有2个语义,具体取决于其重置模式。 当EventWaitHandle处于AutoReset模式时,所有等待的线程都被阻塞,直到事件发出信号,一旦事件发出信号,后续的等待操作就会重置其状态,线程再次调用等待块。
但是,如果EventWaitHandle处于ManualReset模式,它将保持信号状态,直到你手动调用Reset,这意味着如果一个EventWaitHandle发出信号并且一个线程在紧密循环中正在调用wait,则该线程将不会阻止直到在事件上手动调用Reset,因此请考虑此假设情景
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);
}
上面的循环将占用你的大部分CPU,直到其他一些线程调用h1.Reset(),这将使SignalAndWait阻塞。
希望这有帮助。
有关详细信息,请查看 http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx