PerformanceCounter的创建需要很长时间 [英] PerformanceCounter creation take a LONG time

查看:304
本文介绍了PerformanceCounter的创建需要很长时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用电荷平衡系统,因此我需要了解每台机器的电荷. PerformanceCounter似乎是要走的路,但是创建第一个需要38到60秒.但是,随后的每个新Counter或"NextValue"调用几乎都是即时的.

I'm working on a charge balancing system and thus I need to know the charge of each machine. PerformanceCounter seem the way to go, but creating the first one take between 38 and 60 sec. Each subsequent new Counter or 'NextValue' call is nearly instant however.

这是我正在使用的代码:

Here is the code I'm using :

[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);
    }
}

研究

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

创建新的System.Diagnostics.PerformanceCounter很慢

我尝试使用其他构造函数并给出精确的"MachineName",但它没有任何改变.

I tried using the other constructors and giving a precise 'MachineName' but it doesn't change anything.

为什么对PerformanceCounter的调用很慢?

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

根据这两个线程,问题似乎与性能计数器是共享资源这一事实有关.但是我不明白如何解决这个问题.

According to this two threads, the problem seem to be about the fact that performance counters are a shared resource. However I don't understand how I could solve that.

在Administrator中运行Visual Studio可以将第一次创建的时间从38秒加速"到26秒,因此也无法解决问题.

Running Visual Studio in Administrator 'accelerate' the first creation from 38 sec to 26 sec, so it doesn't solve the problem either.

感谢您的帮助.

推荐答案

我在您的计算机上尝试了您的代码,而PerformanceCounter的构造函数获得了2.5秒以上的时间.我无法调试.NET源代码(我正在运行VS2013 Express Edition,Windows 7 64b ),但是我做了一系列实验:

I tried your code on my machine and I got >2.5 seconds for the constructor of the PerformanceCounter. I was not able to debug the .NET Source Code (I'm running VS2013 Express Edition, Windows 7 64b) but I did a series of experinets:

  1. 我调用了PerformanceCounter的默认构造函数.它会立即执行.
  2. 使用性能监视器,我检查了与网络相关的活动.我什么都没看到.
  3. 我监视了内存占用量.我看到在调用第一个参数化的构造函数时,我在代码的内存占用量中添加了约2.5MB.
  4. 使用perfmon,我检查了已使用的互斥量,信号量和其他同步对象的数量是否存在峰值.没什么异常的.
  5. 在不同数量的进程处于活动状态时,我多次测试了该代码.我看到了巨大的变化.有时我得到1.4秒,有时我得到2.7有时我得到5秒.
  6. 我已经打开了一个GUI监视会话并运行了代码,但看不到任何收获.
  1. I called the default constructor of the PerformanceCounter. It executes instantly.
  2. Using perfmon I checked the networking related activity. I saw nothing peculiar.
  3. I monitored the memory footprint. I saw that when calling the first parametrized constructor I add ~2.5MB to the memory footprint of the code.
  4. Using perfmon I checked if there's a spike in the count of used mutex, semaphores and other synchronization objects. Nothing unusual happened.
  5. I tested the code in various times while different number of processes were active. I saw that there is great variation. Sometimes i get 1.4 seconds, sometimes I get 2.7 sometimes I get 5 seconds.
  6. I already opened a GUI monitoring session and ran the code but I saw no gain.

所以我相信没有设置问题,答案是 PerformanceCounter构造函数执行复杂的工作,需要花费很多时间才能执行.

So I believe that there is no setup problem and the the answer is that PerformanceCounter constructor does complex work that takes a lot of time to execute.

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

All the events being monitored are software events, that can be tracked by the operating system. So I suppose that when a new PerformanceCounter object is created, the OS has to generate the current state of the machine. That possibly means getting information for all processes, and most of all, storing that information into a readable and fast accessible structure. What I observed is that the more active processes I have, the slower the PerformanceCounter is created. Also the more cores you have, probably the more data you have to collect.

在您发送的最后一个链接中,有一条评论似乎验证了这一理论,但是我认为自2005年以来对自旋锁部分进行了优化.也许最后的手段是调试.NET源以构造PerformanceCounter.但是我认为这就是它的实现方式.

In the last link you sent, there's a comment that seems to validate this theory but I suppose the spinlock part was optimized since 2005. Probably the measure of last resort is to debug the .NET source for constructing the PerformanceCounter. However I think that this is just how it's implemented.

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

What I would do is creating the PerformanceCounter objects I need during the initialization phase of the application.

这篇关于PerformanceCounter的创建需要很长时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆