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

Jim*_*Jim 4 c# performancecounter

我看到的是,我的性能计数器实例被添加到超出指定计数器的性能类别中的其他计数器。

在此处输入图片说明

鉴于以下代码:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

来自 PerfMon:

在此处输入图片说明

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

我究竟做错了什么?

Jim*_*Jim 5

我找到了我自己的答案。从这里的文档

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

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

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

  • 反直觉。无价。你先生是一位大师级的文字匠。 (2认同)