2009-08-03 9 views
8

Sto provando a misurare il tempo necessario per eseguire un pezzo di codice sul mio server di produzione. Mi piacerebbe monitorare queste informazioni in tempo reale, quindi ho deciso di dare a Performance Analyzer un mago. Capisco da MSDN che ho bisogno di creare un contatore di prestazioni AverageTimer32 e AverageBase, che ho debitamente avuto. Incremento il contatore nel mio programma, e posso vedere il CallCount andare su e giù, ma il tempo medio è sempre zero. Che cosa sto facendo di sbagliato?Come utilizzare PerformanceCounterType AverageTimer32?

Ecco uno snippit di codice:

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

risposta

4

Prima di tutto, allegando per i contatori delle prestazioni è piuttosto costoso, così si dovrebbe cercare di mantenere le istanze globali vivono a loro, invece di aprire e chiudere ogni volta.

Sembra che tu abbia l'idea giusta, è più o meno quello che facciamo nel nostro codice di monitoraggio delle prestazioni. Tuttavia non lo facciamo. Valore successivo immediatamente prima dell'aggiornamento - quindi proverei a smettere di farlo inizialmente.

Sei sicuro che Environment.TickCount - init_call_time non è un periodo di tempo così breve da essere valutato a 0? Environment.TickCount non ha una grande risoluzione, la classe System.Diagnostics.Stopwatch ha una precisione molto migliore.

+0

>> si dovrebbe cercare di mantenere le istanze globali Come ti suggerisco di fare questo in un'applicazione web? Dovrei forse aggiungere del codice a Application_Start per istanziare i contatori e memorizzarli in una variabile Application? –

+0

Il tempo di esecuzione medio è di circa 1,5 secondi - 3 secondi a seconda, quindi presumo che sia abbastanza lungo per Environment.TickCount, tuttavia proverò il cronometro. –

2

Dando per scontato che non multi-threaded, allora questo dovrebbe essere

// 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 

Se vi trovate in una situazione più threaded poi:

// 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

Questa è un'applicazione ASP.net ospitata in IIS, quindi impostare RawValue è ancora una buona idea? –

+0

Si consiglia di utilizzare l'incremento reimpostando il cronometro ogni volta e si dispone di un cronometro per thread (il thread statico farebbe) – ShuggyCoUk