2009-08-03 6 views
8

J'essaye de mesurer le temps qu'il faut pour exécuter un morceau de code sur mon serveur de production. J'aimerais surveiller cette information en temps réel, j'ai donc décidé de donner un coup de fouet à Performance Analyzer. Je comprends de MSDN que j'ai besoin de créer à la fois un compteur de performance AverageTimer32 et un AverageBase, que j'ai dûment. J'incrémente le compteur dans mon programme, et je peux voir le CallCount monter et descendre, mais le AverageTime est toujours zéro. Qu'est-ce que je fais mal?Comment utiliser PerformanceCounterType AverageTimer32?

Voici un snippit de code:

long init_call_time = Environment.TickCount; 

// *** 
// Lots and lots of code... 
// *** 

// Count number of calls 
PerformanceCounter perf = 
    new PerformanceCounter("Cat", "CallCount", "Instance", false); 
perf.Increment(); 
perf.Close(); 

// Count execution time 
PerformanceCounter perf2 = 
    new PerformanceCounter("Cat", "CallTime", "Instance", false); 
perf2.NextValue(); 
perf2.IncrementBy(Environment.TickCount - init_call_time); 
perf2.Close(); 

// Average base for execution time 
PerformanceCounter perf3 = 
    new PerformanceCounter("Cat", "CallTimeBase", "Instance", false); 
perf3.Increment(); 
perf3.Close(); 

perf2.NextValue(); 

Répondre

4

Tout d'abord, la fixation aux compteurs de performance est assez cher, vous devriez donc essayer de garder les instances mondiales vivent à eux au lieu d'ouvrir et les fermer à chaque fois.

Vous semblez avoir la bonne idée, c'est à peu près ce que nous faisons dans notre code de surveillance des performances. Cependant, nous ne faisons pas .NextValue immédiatement avant de les mettre à jour - donc j'essaierais de ne pas le faire au départ.

Etes-vous également certain que Environment.TickCount - init_call_time n'est pas si petit qu'il est évalué à 0? Environnement.TickCount n'a pas une grande résolution, la classe System.Diagnostics.Stopwatch a une bien meilleure précision.

+0

>> vous devriez essayer de garder les instances mondiales Comment proposeriez-vous le faire dans une application web? Devrais-je ajouter du code à Application_Start pour instancier les compteurs et les stocker dans une variable Application? –

+0

Le temps d'exécution moyen est d'environ 1,5 secondes - 3 secondes selon, donc je suppose que c'est assez long pour Environment.TickCount, mais je vais essayer le chronomètre. –

2

En supposant que vous n'êtes pas multithread alors ce devrait être

// cached somewhere 
var perf2 = new PerformanceCounter("Cat", "CallTime", "Instance", false); 
var sw = new Stopwatch(); 

// where ever you are setting init_call_time 
sw.Start(); 

// then when the task has finished 
sw.Stop(); 
perf2.RawValue = sw.ElapsedMilliseconds; // or tick, whatever you want to use 

Si vous êtes dans une situation multifil alors:

// cached somewhere 
var perf2 = new PerformanceCounter("Cat", "CallTime", "Instance", false); 

[ThreadStatic] 
Stopwatch sw; 

// where ever you are setting init_call_time 
if (sw == null) 
    sw = new Stopwatch(); 
sw.Start(); 

// then when the task has finished 
sw.Stop(); 
perf2.IncrementBy(sw.ElapsedMilliseconds); // or tick, whatever you want to use 
sw.Reset(); 
+0

Il s'agit d'une application ASP.net hébergée dans IIS. La définition de RawValue est-elle toujours une bonne idée? –

+0

Vous voudriez utiliser l'incrément réinitialiser le chronomètre à chaque fois et avoir un chronomètre par thread (thread statique ferait) – ShuggyCoUk