Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用PerformanceCounter.NextValue时cpu高_C#_Performance_Performancecounter - Fatal编程技术网

C# 使用PerformanceCounter.NextValue时cpu高

C# 使用PerformanceCounter.NextValue时cpu高,c#,performance,performancecounter,C#,Performance,Performancecounter,我们已经为我们的企业应用程序创建了一个监控应用程序,该应用程序将监控我们的应用程序性能计数器。我们监控一对系统计数器(内存、cpu)和10个左右的自定义性能计数器。我们监控7到8个前男友,所以我们每隔几秒钟检查80个计数器 一切都很好,除了当我们在计数器上循环时,cpu会受到冲击,在我非常好的机器上大约15%,但在其他机器上,我们已经看到了更高的冲击。我们希望我们的监控应用程序在后台独立运行,查找问题,而不是占用大量cpu 这个简单的c#类很容易复制这一点。这将加载所有进程并为每个进程获取专用字

我们已经为我们的企业应用程序创建了一个监控应用程序,该应用程序将监控我们的应用程序性能计数器。我们监控一对系统计数器(内存、cpu)和10个左右的自定义性能计数器。我们监控7到8个前男友,所以我们每隔几秒钟检查80个计数器

一切都很好,除了当我们在计数器上循环时,cpu会受到冲击,在我非常好的机器上大约15%,但在其他机器上,我们已经看到了更高的冲击。我们希望我们的监控应用程序在后台独立运行,查找问题,而不是占用大量cpu

这个简单的c#类很容易复制这一点。这将加载所有进程并为每个进程获取专用字节。我的机器有150道工序。CallNextValue大约需要1.4秒和16%的cpu

class test
{
    List<PerformanceCounter> m_counters = new List<PerformanceCounter>();

    public void Load()
    {
        var processes = System.Diagnostics.Process.GetProcesses();
        foreach (var p in processes)
        {
            var Counter = new PerformanceCounter();
            Counter.CategoryName = "Process";
            Counter.CounterName = "Private Bytes";
            Counter.InstanceName = p.ProcessName;

            m_counters.Add(Counter);
        }
    }

    private void CallNextValue()
    {
        foreach (var c in m_counters)
        {
            var x = c.NextValue();              
        }
    }
}
类测试
{
列表m_计数器=新列表();
公共空荷载()
{
var processs=System.Diagnostics.Process.GetProcesses();
foreach(过程中的var p)
{
var Counter=新性能计数器();
Counter.CategoryName=“进程”;
Counter.CounterName=“专用字节”;
Counter.InstanceName=p.ProcessName;
m_计数器。添加(计数器);
}
}
私有void CallNextValue()
{
foreach(m_计数器中的var c)
{
var x=c.NextValue();
}
}
}
在windows中的Perfmon.exe中执行同样的操作,并添加计数器进程-在选择所有进程的情况下使用私有字节,我发现几乎没有占用cpu,而且它还绘制了所有进程的图形

那么Perfmon是如何获得这些值的呢?是否有更好的/不同的方法以c#形式获取这些性能计数器

我试着使用RawValue而不是NextValue,我看不出有什么区别


我在C++中玩了PDH调用(PDHopEngQuess,PDHCraceQueDebug……)。我的第一个测试在cpu上似乎并不容易,但我还没有创建一个好的示例。

我对.NET性能计数器API不是很熟悉,但我对这个问题有一个猜测

Windows内核实际上没有API来获取关于一个进程的详细信息。相反,它有一个API,可以调用该API“获取所有进程的所有信息”。这是一个相当昂贵的API调用。每次对其中一个计数器执行c.NextValue()时,系统都会进行该API调用,丢弃99%的数据,并返回有关您询问的单个进程的数据

PerfMon.exe使用相同的PDH API,但它使用通配符查询——它创建一个查询,一次获取所有进程的数据,因此它实际上每秒只调用一次c.NextValue(),而不是调用它N次(其中N是进程数)。它可以取回大量数据(所有进程的数据),但扫描这些数据的成本相对较低


我不确定.NET性能计数器API是否支持通配符查询。PDH API确实如此,执行一个通配符查询要比执行一大堆单实例查询便宜得多。

我对.NET性能计数器API不是很熟悉,但我对这个问题有一个猜测

Windows内核实际上没有API来获取关于一个进程的详细信息。相反,它有一个API,可以调用该API“获取所有进程的所有信息”。这是一个相当昂贵的API调用。每次对其中一个计数器执行c.NextValue()时,系统都会进行该API调用,丢弃99%的数据,并返回有关您询问的单个进程的数据

PerfMon.exe使用相同的PDH API,但它使用通配符查询——它创建一个查询,一次获取所有进程的数据,因此它实际上每秒只调用一次c.NextValue(),而不是调用它N次(其中N是进程数)。它可以取回大量数据(所有进程的数据),但扫描这些数据的成本相对较低


我不确定.NET性能计数器API是否支持通配符查询。PDH API确实如此,执行一个通配符查询要比执行一大堆单实例查询便宜得多。

很抱歉回答了这么长时间,但我现在才发现您的问题。无论如何,如果有人需要额外帮助,我有一个解决方案:

我对我的定制流程做了一些研究,我知道当我们有一个像

    PerformanceCounter ourPC = new PerformanceCounter("Process", "% Processor time", "processname", true);
    ourPC.NextValue();
然后,我们的性能计数器的NextValue()将显示(逻辑核的数量*进程的任务管理器cpu负载)值,我想这是一种合乎逻辑的东西

因此,您的问题可能是任务管理器中有轻微的CPU负载,因为它知道您有一个多核CPU,尽管性能计数器按上述公式计算

我为您的问题找到了一种可能的解决方案,因此您的代码应该重写如下:

private void CallNextValue()
{
    foreach (var c in m_counters)
    {
        var x = c.NextValue() / Environment.ProcessorCount;              
    }
}
无论如何,我不建议您使用Environment.ProcessorCount,尽管我已经使用过它:我只是不想在我的短代码段中添加太多代码

如果您遵循以下链接,您可以看到一个很好的方法来确定系统中有多少逻辑核(是的,如果您有core i7,例如,您必须计算逻辑核,而不是物理核):


祝你好运

很抱歉回答了这么长时间,但我现在才发现你的问题。无论如何,如果有人需要额外帮助,我有一个解决方案:

我对我的定制流程做了一些研究,我知道当我们有一个像

    PerformanceCounter ourPC = new PerformanceCounter("Process", "% Processor time", "processname", true);
    ourPC.NextValue();
然后,我们的性能计数器的NextValue()将显示(逻辑核的数量*进程的任务管理器cpu负载)值,我想这是一种合乎逻辑的东西

所以,你的问题可能是你有轻微的