2009-08-03 9 views
8

Estoy tratando de medir el tiempo que lleva ejecutar un fragmento de código en mi servidor de producción. Me gustaría monitorear esta información en tiempo real, así que decidí dar un vistazo a Performance Analyzer. Entiendo por MSDN que necesito crear un contador de rendimiento AverageTimer32 y un contador de rendimiento AverageBase, que tendré debidamente. Incremento el contador en mi programa, y ​​puedo ver que el CallCount sube y baja, pero el AverageTime siempre es cero. ¿Qué estoy haciendo mal?¿Cómo uso PerformanceCounterType AverageTimer32?

Aquí hay una snippit de código:

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

Respuesta

4

En primer lugar, la fijación de los contadores de rendimiento es bastante caro, por lo que debe tratar de mantener las instancias globales viven a ellos en vez de abrir y cerrar ellos cada vez.

Parece que tiene la idea correcta, eso es más o menos lo que hacemos en nuestro código de supervisión del rendimiento. Sin embargo, no hacemos .NextValue inmediatamente antes de actualizar estos, así que trataría de dejar de hacer eso inicialmente.

¿Está seguro de que Environment.TickCount - init_call_time no es un período de tiempo tan pequeño que se evalúa como 0? Environment.TickCount no tiene una gran resolución, la clase System.Diagnostics.Stopwatch tiene una precisión mucho mejor.

+0

>> usted debe tratar de mantener las instancias globales ¿Cómo sugieren hacer esto en una aplicación web? ¿Debo agregar algún código a Application_Start para crear instancias de los contadores y almacenarlos en una variable de aplicación? –

+0

El tiempo promedio de ejecución es de aproximadamente 1.5 segundos - 3 segundos dependiendo, así que supongo que es lo suficientemente largo para Environment.TickCount, sin embargo, voy a probar el cronómetro. –

2

Suponiendo que usted es no multiproceso entonces esto debe ser

// 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 se encuentra en una situación multi-hilo a continuación:

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

Esta es una aplicación ASP.net alojada en IIS, por lo que establecer RawValue sigue siendo una buena idea? –

+0

Le conviene usar el incremento reiniciando el cronómetro cada vez y tener un cronómetro por hilo (lo haría el hilo estático) – ShuggyCoUk