2009-08-03 26 views
8

我正在測量在生產服務器上執行一段代碼所需的時間。我想實時監控這些信息,所以我決定給性能分析器一個高手。我從MSDN瞭解到,我需要創建AverageTimer32和AverageBase性能計數器,而這正是我應該擁有的。我在程序中增加了計數器,我可以看到CallCount上下移動,但AverageTime總是爲零。我究竟做錯了什麼?如何使用PerformanceCounterType AverageTimer32?

下面是一個代碼SNIPPIT:

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

回答

4

首先,注重性能計數器是相當昂貴的,所以你應該儘量保持全局實例住他們,而不是開在每次關閉它們。

您似乎有正確的想法,這幾乎是我們在我們的性能監控代碼中所做的。但是,在更新這些之前,我們不會這樣做.NextValue - 所以我會嘗試在最初停止這樣做。

您是否確定Environment.TickCount - init_call_time不是很短的時間,它的計算結果爲0? Environment.TickCount不具有很好的分辨率,System.Diagnostics.Stopwatch類具有更好的準確性。

+0

>>你應該儘量保持全局實例 你會如何建議在Web應用程序這樣做呢?我是否應該向Application_Start添加一些代碼來實例化計數器並將它們存儲在應用程序變量中? – 2009-08-04 10:45:14

+0

平均執行時間大約爲1.5秒-3秒,具體取決於,因此我認爲這足以滿足Environment.TickCount的要求,但我會嘗試秒錶。 – 2009-08-04 10:46:51

2

假設你是不是多線程那麼這應該是

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

如果你是在一個多線程的情況下,則:

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