2009-06-23 5 views
3

Ich habe gerade die Testversion von ANTS Performance Profiler from Red Gate heruntergeladen und untersuche den Code meines Teams. Sofort merke ich, dass es einen bestimmten Codeabschnitt gibt, von dem ANTS berichtet, dass er bis zu 99% CPU-Zeit verbraucht.Kann ein Aufruf von WaitHandle.SignalAndWait für Leistungsprofilzwecke ignoriert werden?

Ich bin völlig mit ANTS oder Leistungsprofil im Allgemeinen nicht vertraut (das heißt, abgesehen von Selbstprofilierung mit, was ich bin sicher ist extrem grob und verpönten Methoden wie double timeToComplete = (endTime - startTime).TotalSeconds), so bin ich das Hantieren noch um mit der Anwendung und herauszufinden, wie es verwendet wird. Aber ich rief den Entwickler an, der für den fraglichen Code verantwortlich war und seine unmittelbare Reaktion war: "Ja, das überrascht mich nicht, dass es das sagt; aber dieser Code ruft SignalAndWait [was ich für mich selbst sehen konnte, dank ANTS] an benutzt keine CPU, es sitzt nur da und wartet auf etwas, was zu tun ist. " Er riet mir, diesen Code einfach zu ignorieren und nach etwas zu suchen, das ich sonst finden könnte.

Meine Frage: Ist es wahr, dass SignalAndWait KEINEN CPU-Overhead benötigt (und wenn ja, wie ist das möglich?), Und ist es vernünftig, dass ein Leistungsprofiler 99% CPU-Zeit benötigt? Ich finde das besonders merkwürdig, denn wenn es bei 99% liegt, würde das bedeuten, dass unsere Anwendung oft untätig ist, oder? Und doch ist seine Leistung in letzter Zeit eher träge geworden.

Wie ich schon sagte, ich bin wirklich nur ein Anfänger, wenn es um dieses Tool geht, und ich weiß nichts über die WaitHandle-Klasse. JEDE Information, die mir hilft, zu verstehen, was hier vor sich geht, würde geschätzt werden.

Antwort

1

Ein WaitHandle bringt Ihren Thread tatsächlich in den Schlaf.

Der zusätzliche Bonus ist, dass Sie Timeouts auf diesen Handles setzen können, so dass sie nach einer gewissen Zeit aufwachen können.

Sie können das WaitHandle auch von einem anderen Thread (zB Application Exit usw.) signalisieren und sie sofort WakeUp.

Ich persönlich bevorzuge ein Waithandle mit einem Short-Timeout über einen Thread.Sleep mit demselben Timeout, wie wenn ein Schlaf gestartet wird es muss Rückkehr, bevor Sie den Betrieb wieder aufnehmen kann, während ein Waithandle sofort wieder aufgenommen werden kann, falls erforderlich.

0

Ich denke, Sie könnten einen schwerwiegenden Fehler in Ihrem Code haben. EventWaitHandle hat 2 Semantiken abhängig von seinem Reset-Modus. Wenn sich EventWaitHandle im AutoReset-Modus befindet, werden alle wartenden Threads blockiert, bis das Ereignis signalisiert wird. Sobald das Ereignis ein Signal ist, setzen nachfolgende Warteoperationen seinen Status zurück und der Thread ruft Wait Block erneut darauf auf.

Wenn sich das EventWaitHandle jedoch im ManualReset-Modus befindet, wird es so lange signalisiert, bis Sie es manuell zurücksetzen, dh wenn ein EventWaitHandle signalisiert wird und ein Thread in einer engen Schleife darauf wartet, wird dieser Thread dieses hyphothetical Szenario manuell auf das Ereignis nicht blockieren, bis zurücksetzen genannt wird, so betrachten

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); 
} 

die Schleife oben essen die meisten Ihrer CPU, bis einem anderen Thread ruft h1.Reset(), die SignalAndWait Blöcke machen.

Hoffe, das hilft.

Für weitere Informationen besuchen Sie http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx

out
Verwandte Themen