性能计数器实例跨越不同的性能计数器

时间:2014-02-24 22:44:01

标签: c# performancecounter

我所看到的是我的性能计数器实例正被添加到性能类别中指定计数器之外的其他计数器。

enter image description here

给出以下代码:

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication26
{
    class Program
    {
        static void Main(string[] args)
        {
            string category = "Foo";
            string categoryHelp = "Test counters";
            string fooCounter1Name = "Test Foo counter 1";
            string fooCounter1InstanceName = fooCounter1Name + "Instance";
            string fooCounter2Name = "Test Foo counter 2";
            string fooCounter2InstanceName = fooCounter2Name + "Instance";

            if (PerformanceCounterCategory.Exists(category))
                PerformanceCounterCategory.Delete(category);

            var counterCreationDataCollection = new CounterCreationDataCollection();
            counterCreationDataCollection.Add(new CounterCreationData(fooCounter1Name, "", PerformanceCounterType.RateOfCountsPerSecond64));
            counterCreationDataCollection.Add(new CounterCreationData(fooCounter2Name, "", PerformanceCounterType.RateOfCountsPerSecond64));

            PerformanceCounterCategory.Create(category, categoryHelp, PerformanceCounterCategoryType.MultiInstance, counterCreationDataCollection);

            PerformanceCounter fooCounter1Instance = new PerformanceCounter();
            fooCounter1Instance.CategoryName = category;
            fooCounter1Instance.CounterName = fooCounter1Name;
            fooCounter1Instance.InstanceName = fooCounter1InstanceName;
            fooCounter1Instance.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
            fooCounter1Instance.ReadOnly = false;

            PerformanceCounter fooCounter2Instance = new PerformanceCounter();
            fooCounter2Instance.CategoryName = category;
            fooCounter2Instance.CounterName = fooCounter2Name;
            fooCounter2Instance.InstanceName = fooCounter2InstanceName;
            fooCounter2Instance.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
            fooCounter2Instance.ReadOnly = false;

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

            var task = Task.Factory.StartNew(() =>
            {
                while (!cancellationTokenSource.IsCancellationRequested)
                {
                    fooCounter1Instance.Increment();
                    fooCounter2Instance.Increment();
                    SpinWait.SpinUntil(() => false, 500);
                }
            }, cancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);

            Console.WriteLine("Press Enter to quit.");
            Console.ReadLine();

            cancellationTokenSource.Cancel();
            task.Wait(10000);
        }
    }
}

为什么实例会在两个计数器中显示?

来自PerfMon:

enter image description here

我希望实例(fooCounter1InstanceName)只显示在“Test Foo counter 1”计数器下,但它也列在“Test Foo counter 2”下面。更有趣的是,该实例可用于在PerfMon中进行选择,但是值仅在正确的计数器名称下写入实例,例如, “Test Foo counter 1”计数器中的fooCounter1InstanceName和“Test Foo counter 2”计数器中的fooCounter2InstanceName。

我做错了什么?

1 个答案:

答案 0 :(得分:4)

我找到了自己的答案。来自文档here

  

在某些情况下,类别被细分为实例,其中   跟踪有关一个类别的对象多次出现的数据   涉及到。 实例适用于整个类别,而不是   个别计数器。一个类别中的每个计数器都有每个实例   为该类别定义。例如,Process类别包含   名为Idle和System的实例。流程中的每个柜台   因此,类别包含每个实例的数据,显示信息   关于空闲进程或系统进程。

这意味着我应该定义诸如“每秒读取#个消息”和“每秒发送的#个消息”之类的计数器,然后为该类别创建一个实例,并且在每个计数器下面将是一个“视图”该实例可能会或可能不会被写入。

这似乎是反直觉的(双关语),因为有些计数器不会写入值,所以为什么列出该计数器下的实例以及为什么在设置计数器实例时指定实例名称但给性能监视器的用户如果一个计数器不适用于该实例的印象?