当我执行以下程序并查看性能计数器时,结果对我来说没有意义。当我期望~0.1或~100时,平均值为零,最小/最大值为~0.4。
我的问题是什么?
代码
class Program
{
const string CategoryName = "____Test Category";
const string CounterName = "Average Operation Time";
const string BaseCounterName = "Average Operation Time Base";
static void Main(string[] args)
{
if (PerformanceCounterCategory.Exists(CategoryName))
PerformanceCounterCategory.Delete(CategoryName);
var counterDataCollection = new CounterCreationDataCollection();
var avgOpTimeCounter = new CounterCreationData()
{
CounterName = CounterName,
CounterHelp = "Average Operation Time Help",
CounterType = PerformanceCounterType.AverageTimer32
};
counterDataCollection.Add(avgOpTimeCounter);
var avgOpTimeBaseCounter = new CounterCreationData()
{
CounterName = BaseCounterName,
CounterHelp = "Average Operation Time Base Help",
CounterType = PerformanceCounterType.AverageBase
};
counterDataCollection.Add(avgOpTimeBaseCounter);
PerformanceCounterCategory.Create(CategoryName, "Test Perf Counters", PerformanceCounterCategoryType.SingleInstance, counterDataCollection);
var counter = new PerformanceCounter(CategoryName, CounterName, false);
var baseCounter = new PerformanceCounter(CategoryName, BaseCounterName, false);
for (int i = 0; i < 500; i++)
{
var sw = Stopwatch.StartNew();
Thread.Sleep(100);
sw.Stop();
Console.WriteLine(string.Format("t({0}) ms({1})", sw.Elapsed.Ticks, sw.Elapsed.TotalMilliseconds));
counter.IncrementBy(sw.Elapsed.Ticks);
baseCounter.Increment();
}
Console.Read();
}
}
效果计数器屏幕截图 Performance Counter Screenshot http://friendfeed-media.com/50028bb6a0016931a3af5122774b56f93741bb5c
答案 0 :(得分:33)
System.Diagnostics API包含一个非常微妙的混乱源:System.Diagnostics'ticks'与DateTime或TimeSpan'ticks'不同!
如果您使用StopWatch.ElapsedTicks而不是StopWatch.Elapsed.Ticks,它应该有效。
documentation包含有关此内容的更多信息。
答案 1 :(得分:9)
如果您要设置AverageTimer32
性能计数器而不是TimeSpan
,则可以执行以下转换:
Stopwatch
答案 2 :(得分:0)
这是一个旧帖子,但我想我会插话。微软的某个人告诉我,我不应该使用TimeSpan
,StopWatch
或DateTime
时与Performance Counters合作。相反,他建议在我的项目中添加以下本机方法:
internal static class NativeMethods
{
[DllImport("Kernel32.dll")]
public static extern void QueryPerformanceCounter(ref long ticks);
}
当递增计数器时,他建议这样做:
public void Foo()
{
var beginTicks = 0L;
var endTicks = 0L;
NativeMethods.QueryPerformanceCounter(ref beginTicks);
// Do stuff
NativeMethods.QueryPerformanceCounter(ref endTicks);
this.Counter.IncrementBy(endTicks - beginTicks);
this.BaseCounter.Increment();
}