2009-06-23 5 views
3

Je viens de télécharger la version d'essai de ANTS Performance Profiler from Red Gate et j'étudie une partie du code de mon équipe. Immédiatement, je remarque qu'il y a une section particulière de code que ANTS rapporte comme mangeant jusqu'à 99% du temps CPU. Je ne suis absolument pas familier avec ANTS ou le profilage de performance en général (c'est-à-dire, en dehors de l'auto-profilage en utilisant ce que je suis sûr sont des méthodes extrêmement grossières et désapprouvées comme double timeToComplete = (endTime - startTime).TotalSeconds), donc je bidouille encore avec l'application et comprendre comment il est utilisé. Mais j'ai immédiatement appelé le développeur responsable du code en question et sa réaction immédiate a été "Ouais, cela ne me surprend pas, mais ce code appelle SignalAndWait [que je pouvais voir moi-même, grâce à ANTS], qui n'utilise pas de CPU, il reste là à attendre quelque chose à faire. " Il m'a conseillé d'ignorer ce code et de chercher tout ce que je pourrais trouver. Ma question: est-il vrai que SignalAndWait ne nécessite AUCUN surcoût CPU (et si oui, comment cela est-il possible?), Et est-il raisonnable qu'un profileur de performances le considère comme prenant 99% du temps CPU? Je trouve cela particulièrement curieux parce que, si c'est à 99%, cela voudrait dire que notre application est souvent inactive, n'est-ce pas? Et pourtant, ses performances sont devenues plutôt lentes dernièrement. Comme je l'ai dit, je ne suis vraiment qu'un débutant en ce qui concerne cet outil, et je ne sais rien de la classe WaitHandle. Donc toute information pour m'aider à comprendre ce qui se passe ici serait appréciée. Un WaitHandle met en effet votre thread en veille.Un appel à WaitHandle.SignalAndWait peut-il être ignoré à des fins de profilage de performances?

Répondre

1

Le bonus supplémentaire est que vous pouvez définir des délais d'attente sur ces poignées afin qu'ils puissent se réveiller après un certain temps.

Vous pouvez également signaler le WaitHandle à partir d'un autre thread (par exemple, une sortie d'application, etc) et ils se réveillent immédiatement.

Personnellement, je préfère un WaitHandle avec un délai d'attente court sur une Thread.Sleep avec le même délai d'attente, comme quand un sommeil est lancé, il doit retour avant de pouvoir reprendre l'opération, tandis qu'un WaitHandle peut reprendre immédiatement si nécessaire.

0

Je pense que vous pourriez avoir un bug sérieux dans votre code. EventWaitHandle a 2 sémantiques en fonction de son mode de réinitialisation. Lorsque EventWaitHandle est en mode AutoReset, tous les threads en attente sont bloqués jusqu'à ce que l'événement soit signalé, une fois l'événement signalé, les opérations d'attente suivantes réinitialisent son état et le thread appelle de nouveau le bloc d'attente. Cependant, si le EventWaitHandle est en mode ManualReset, il restera signalé jusqu'à ce que vous appeliez Reset manuellement, cela signifie que si un EventWaitHandle est signalé et qu'un thread appelle, attendez-le dans une boucle serrée, ce thread sera pas bloquer jusqu'à ce que Reset est appelé manuellement sur l'événement, alors pensez à ce scénario hyphothetical

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

la boucle au-dessus mangera la majeure partie de votre CPU jusqu'à ce que certains autres appels fil h1.Reset(), qui fera des blocs SignalAndWait.

Espérons que cela aide. Pour plus d'informations, consultez http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx

Questions connexes