【问题标题】:Installing a Total instance for Performance Counters为性能计数器安装 Total 实例
【发布时间】:2010-11-06 07:37:27
【问题描述】:

VS 2005、C# 2.0、.NET 2.0/3.0、Win2003

我正在尝试为 MultiInstance 安装一组性能计数器。我注意到,即使没有其他实例,某些系统性能计数器类别也设法保持“total”处于活动状态。 ASP.NET Apps 2.0.50727 就是一个例子。

所以我一直在尝试复制这个。我在 Installer 类中创建了以下例程,然后将其添加到安装项目中的自定义操作中。

public override void Install(System.Collections.IDictionary stateSaver)
{
    //Debugger.Break();
    CounterCreationData data = new CounterCreationData("ZCounter", "ZCtrHelp", PerformanceCounterType.NumberOfItems32);
    PerformanceCounterCategory.Create("ZCategory", "ZCatHelp", PerformanceCounterCategoryType.MultiInstance, new CounterCreationDataCollection(new CounterCreationData[] { data }));
    PerformanceCounter counter = new PerformanceCounter();
    counter.CategoryName = "ZCategory";
    counter.CounterName = "ZCounter";
    counter.InstanceName = "ZTotal";
    counter.InstanceLifetime = PerformanceCounterInstanceLifetime.Global;
    counter.ReadOnly = false;
    counter.RawValue = 0;
    base.Install(stateSaver);
}

如果我取消注释 Debugger.Break() 行并逐步执行,我可以看到计数器实际上是使用正确的实例名称创建的,并且 Visual Studio Server Explorer 会显示该实例以及设置为 Global 的 InstanceLifetime。我没有在安装程序中调用 RemoveInstance() 方法。

不过,在安装程序完成几秒钟后,该实例会从性能监视器和 VS 服务器资源管理器中消失。我如何让它粘住?或者我可以吗?

【问题讨论】:

    标签: c# .net windows installation performancecounter


    【解决方案1】:

    尝试使用“PerformanceCounterCategoryType.SingleInstance”创建类别。

    【讨论】:

    • 我可能可以,但这违背了拥有“Total”实例(用于聚合所有其他实例的结果)的目的。我知道这是可能的;正如我所提到的,ASP.NET 正在以某种方式做到这一点。也许它使用其他一些过程来将“Total”实例保留在计数器集中?
    • 我不知道“其他过程”的事情 - 但如果有这样的野兽会感兴趣。我会创建 SingleInstance 计数器,每次更新 MultiInstance/特定实例时,我都会将 SingleInstance/global-one 更新相同的值。 IE。手动进行“聚合”。
    • 对不起,我之前没有看到这条评论。两个问题: 1) SingleInstance category 表示没有命名实例。 2)我知道我可以更新多个实例(一个“总”和一个“流程”实例)——这不是我的问题。问题是“当根本没有实例运行时,我如何保留显示在性能计数器列表中的 MultipleInstance 类别的“总”实例?
    • 是的,你当然是对的。对不起,我有点迟钝。就在两天前,我再次处理性能计数器(顺便说一下“_Total”实例),现在我明白了。 :-)
    【解决方案2】:

    只是一个建议,但请尝试制作

    Counter.ReadOnly = true;
    

    第一次通过,仅当您需要增加计数器时才将其设置为 False。

    如果您将 Counter 设置为只读,您显然需要注释掉该行:

    Counter.RawData = 0;
    

    我相信它在第一次通过时默认设置为 0。

    希望这会有所帮助...

    【讨论】:

    • 我会试试这个,今天告诉你。
    • 迈克:测试失败。如果它起作用了,性能监视器中就会有一个名为“ZTotal”的实例用于该类别和计数器,但实际上没有。
    【解决方案3】:

    AFAIK 只要任何进程具有引用它的活动句柄,全局性能计数器类别就会保持活动状态。系统计数器通过在某些服务中保持对总计数器实例的句柄来实现这一点。

    【讨论】:

      【解决方案4】:

      某些代码必须主动维护计数器。在您能想到的所有实例中,例如 ASP.Net,都有一项服务保持计数器正常运行。

      由于您不满意 _Total 实例仅在您的应用程序的某些实例运行时才处于活动状态,因此您必须编写一些代码来维护应用程序之外的性能计数器。没有魔法。

      您可以编写一个小型服务来满足您的监控需求。这将维护 _Total 计数器。您需要决定更新方案。最简单的方法是让应用程序的每个实例都更新两个实例(它们自己的和 _Total)。

      关于性能计数器的一些背景知识 - 要了解的主要内容是,通常在进程之间共享一个共享内存区域,该区域通过互锁操作进行更新。像 PerfMon(或任何其他应用程序)这样的工具最终会连接到共享内存区域以获取当前值。因此,某些进程必须打开并拥有该共享内存区域。因此,为什么您需要运行代码。 PerfMon 不会为您创建 _Total 实例(它确实有一些相当复杂的计数器组合,允许计算平均值和比率,但没有总和来创建汇总实例)。

      【讨论】:

      • 我认为这是我问题的正确答案。但是,复选标记消失了;我无法选择它作为正确答案。我知道 PerfMon 没有创建 _Total 计数器;我只是不清楚总有一项服务可以使 _Total 计数器保持活动状态。 “PerformanceCounterInstanceLifetime.Global”建议它应该这样做;否则,这个名字有什么意义?顺便说一句,我一点也不反对编写任何数量的代码、服务或其他任何东西。我只是不知道它是如何完成的。我讨厌被认为是一个懒惰的程序员。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多