PerformanceCounter创建需要很长时间

Epi*_*ien 7 c# performance load-balancing performancecounter shared-resource

我正在研究电荷平衡系统,因此我需要知道每台机器的费用.PerformanceCounter似乎要走了,但创建第一个需要38到60秒.然而,每个后续的新计数器或'NextValue'呼叫几乎是即时的.

这是我正在使用的代码:

[TestClass]
public class PerfMon
{
    [TestMethod]
    public void SimpleCreationTest()
    {
        Stopwatch Time = new Stopwatch();
        Time.Start();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds);

        // Create

        PerformanceCounter RAM = new PerformanceCounter("Memory", "Available MBytes");
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => RAM created");

        PerformanceCounter CPU = new PerformanceCounter("Processor", "% Processor Time", "_Total");
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => CPU created");

        PerformanceCounter GC = new PerformanceCounter(".NET CLR Memory", "% Time in GC", "_Global_");
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => GC created");

        // Read

        float Value = RAM.NextValue();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => RAM value is : " + Value);

        Value = CPU.NextValue();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => CPU value is : " + Value);

        Value = GC.NextValue();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => GC value is : " + Value);
    }
}
Run Code Online (Sandbox Code Playgroud)

研究

PerformanceCounter连接远程服务器的速度极慢

创建一个新的System.Diagnostics.PerformanceCounter非常慢

我尝试使用其他构造函数并给出一个精确的'MachineName',但它不会改变任何东西.

为什么对PerformanceCounter的调用很慢?

http://craigandera.blogspot.fr/2005/06/performancecounter-constructor-horribly_21.html

根据这两个线程,问题似乎是性能计数器是共享资源的事实.但是我不明白我怎么解决这个问题.

在管理员中运行Visual Studio会将第一次创建从38秒加速到26秒,因此它也无法解决问题.


谢谢你的帮助.

VAn*_*rei 3

我在我的机器上尝试了你的代码, PerformanceCounter 的构造函数得到了 >2.5 秒的时间。我无法调试 .NET 源代码(我运行的是 VS2013 Express Edition,Windows 7 64b),但我做了一系列的实验:

  1. 我调用了PerformanceCounter 的默认构造函数。它立即执行。
  2. 使用 perfmon 我检查了网络相关活动。我没有看到任何奇怪的东西。
  3. 我监控了内存占用。我发现在调用第一个参数化构造函数时,我向代码的内存占用添加了约 2.5MB。
  4. 我使用 perfmon 检查了使用的互斥体、信号量和其他同步对象的数量是否出现峰值。没有什么异常的事情发生。
  5. 我在不同数量的进程处于活动状态时多次测试了代码。我看到变化很大。有时我得到 1.4 秒,有时我得到 2.7,有时我得到 5 秒。
  6. 我已经打开了一个 GUI 监控会话并运行了代码,但我没有看到任何收获。

所以我相信不存在设置问题,答案是PerformanceCounter 构造函数执行复杂的工作,需要花费大量时间来执行

所有被监控的事件都是软件事件,可以被操作系统跟踪。所以我想当创建一个新的 PerformanceCounter 对象时,操作系统必须生成机器的当前状态。这可能意味着获取所有进程的信息,最重要的是,将该信息存储到可读且快速访问的结构中。我观察到,活动进程越多,创建 PerformanceCounter 的速度就越慢。此外,您拥有的核心越多,您需要收集的数据可能就越多。

在您发送的最后一个链接中,有一条评论似乎验证了这一理论,但我认为自旋锁部分自 2005 年以来已进行了优化。最后的措施可能是调试用于构造 PerformanceCounter 的 .NET 源代码。但我认为这就是它的实施方式。

我要做的是在应用程序的初始化阶段创建我需要的 PerformanceCounter 对象。