我想获取C#中某个应用程序的总体CPU使用总量。我已经找到了许多方法来挖掘进程的属性,但是我只想要进程的CPU使用率,以及想要在TaskManager中获得的总CPU数。

我该怎么做?

评论

stackoverflow.com/questions/4679962/…

这到底是怎么回事?可笑。

#1 楼

您可以使用System.Diagnostics中的PerformanceCounter类。

像这样初始化:

PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;

cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
ramCounter = new PerformanceCounter("Memory", "Available MBytes");


这样的消费: />
public string getCurrentCpuUsage(){
            return cpuCounter.NextValue()+"%";
}

public string getAvailableRAM(){
            return ramCounter.NextValue()+"MB";
} 


评论


不错-但原始来源似乎来自此处:zamov.online.fr/EXHTML/CSharp/CSharp_927308.html

–马特·雷菲(Matt Refghi)
09年6月17日在17:50

根据我的发现,我不得不两次使用cpuCounter.NextValue(),而在它们之间我不得不睡眠(500)

–天使之王47
2010-3-7的2:56

马特是对的。甚至包括错误,例如忘记了“ return”关键字。

–在斜坡51标记
2011年3月3日在1:01

是的,它看起来像是该链接的副本,因此用于引用原始链接的链接将是不错的样式。另一方面,CMS也可以在此处提供答案,因此懒惰的开发人员不必在整个Google上进行搜索即可找到相同的答案。 :o)

–BerggreenDK
2011年4月8日14:40

您将需要两次调用.NextValue,并在两者之间进行一次System.Threading.Thread.Sleep调用(1000ms就足够了)。有关为什么需要这样做的更多信息,请参见blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx,但高级摘要是您需要两个样本才能计算出该值,并且您需要给操作系统一些时间来获得这两个功能。

– C脚
2012年1月24日,下午1:48

#2 楼

超出了要求的数量,但是我使用了额外的计时器代码来跟踪并警告CPU使用率在90分钟以上(持续1分钟或更长时间)。

评论


getRAMCounter()在哪里?

– Dieter B
2014年2月19日的16:00

cpuCounter.NextValue返回一个浮点数。那么为什么将其分配给动态对象呢?那么,为什么要返回该动态对象呢?那么,为什么要尝试在int cpuPercent = getCPUCounter()行中将对象分配给int? (该代码将无法编译。)

–维克
19年8月20日在1:52

#3 楼

花了一些时间阅读了几个看起来很复杂的不同线程后,我想到了这个。我需要一个用于监视SQL Server的8核计算机。对于下面的代码,然后我将“ sqlservr”作为appName传入。

评论


total_cpu应该是PerformanceCounter(“ Processor”),而不是PerformanceCounter(“ Process”)..否则,您只会获得100%*内核数。

–史蒂夫·库克
2014-3-24在2:17



您在哪里将完成设置为true?除非我忽略了某些内容,否则这似乎是一个无休止的循环:while(!done){...}

– Manfred
18年5月2日在4:00

@Manfred确实是一个无尽的循环

–珍妮
18年6月3日在8:22

#4 楼

可以,我知道了!感谢您的帮助!

下面是执行此操作的代码:

private void button1_Click(object sender, EventArgs e)
{
    selectedServer = "JS000943";
    listBox1.Items.Add(GetProcessorIdleTime(selectedServer).ToString());
}

private static int GetProcessorIdleTime(string selectedServer)
{
    try
    {
        var searcher = new
           ManagementObjectSearcher
             (@"\"+ selectedServer +@"\root\CIMV2",
              "SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name=\"_Total\"");

        ManagementObjectCollection collection = searcher.Get();
        ManagementObject queryObj = collection.Cast<ManagementObject>().First();

        return Convert.ToInt32(queryObj["PercentIdleTime"]);
    }
    catch (ManagementException e)
    {
        MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
    }
    return -1;
}


评论


添加获取服务器名称而不是变量selectedServer更好。像这样。string computername = Environment.GetEnvironmentVariable(“ computername”);

–王ave
3月25日在1:56



#5 楼

您可以使用WMI获取CPU百分比信息。如果您具有正确的权限,甚至可以登录到远程计算机。请查看http://www.csharphelp.com/archives2/archive334.html,以了解您可以完成的工作。 >
另请参见CodeProject示例如何:(几乎)通过C#在WMI中进行所有操作。

#6 楼

CMS是正确的,但是如果您在Visual Studio中使用服务器资源管理器并使用“性能计数器”选项卡,那么您可以弄清楚如何获得许多有用的指标。​​

#7 楼

此类每1秒自动轮询一次计数器,并且也是线程安全的:

public class ProcessorUsage
{
    const float sampleFrequencyMillis = 1000;

    protected object syncLock = new object();
    protected PerformanceCounter counter;
    protected float lastSample;
    protected DateTime lastSampleTime;

    /// <summary>
    /// 
    /// </summary>
    public ProcessorUsage()
    {
        this.counter = new PerformanceCounter("Processor", "% Processor Time", "_Total", true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public float GetCurrentValue()
    {
        if ((DateTime.UtcNow - lastSampleTime).TotalMilliseconds > sampleFrequencyMillis)
        {
            lock (syncLock)
            {
                if ((DateTime.UtcNow - lastSampleTime).TotalMilliseconds > sampleFrequencyMillis)
                {
                    lastSample = counter.NextValue();
                    lastSampleTime = DateTime.UtcNow;
                }
            }
        }

        return lastSample;
    }
}


评论


System.DateTime实际上是8字节的值类型,这意味着对DateTime变量的分配不是原子的。此代码在32位平台上不是线程安全的。

– andrewjs
16年7月11日在8:32

#8 楼

这似乎对我有用,例如等待处理器达到特定百分比的示例。

var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
int usage = (int) cpuCounter.NextValue();
while (usage == 0 || usage > 80)
{
     Thread.Sleep(250);
     usage = (int)cpuCounter.NextValue();
}


评论


使用量为0时为什么要睡觉?

– watashiSHUN
16年8月18日在18:27

#9 楼

我不喜欢在所有PerformanceCounter解决方案中增加1秒的停顿时间。相反,我选择使用WMI解决方案。使用1秒等待/停转的原因是为了在使用PerformanceCounter时使读数准确。但是,如果您经常调用此方法并刷新此信息,我建议不要经常发生这种延迟……即使考虑进行异步处理来获取它。此处的摘录使用C#返回WMI中的CPU使用率,并在下面的我的博客文章中添加了该解决方案的完整说明:

评论


请在此处添加答案,而不是链接到您的博客。

– Herman
5月10日21:12

@Herman-我不仅链接到我的博客;我首先给出了一个解释,然后继续提供一个链接,供您在此处发表文章后进行深入解答。

– atconway
5月12日下午3:34

您博客文章中的解决方案就像12行代码。除了尝试吸引人们访问您的博客外,为什么不将其包含在您的答案中?

– Herman
5月12日8:12

链接可能会断开,并且当核心内容为嵌入式时,扫描答案要容易得多。很抱歉在我的其他回复中很苛刻,我在这里不给您带来麻烦。 :)

– Herman
5月12日22:45

由于简短,我还建议在此处复制代码。除此之外,页面上还有一个错误:Cast 中的ManagementObject必须大写,类型区分大小写,并且带有Cast 的代码无法编译。

–那马克
5月29日17:06

#10 楼

public int GetCpuUsage()
{
    var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total", Environment.MachineName);
    cpuCounter.NextValue();
    System.Threading.Thread.Sleep(1000); //This avoid that answer always 0
    return (int)cpuCounter.NextValue();
}

此链接中的原始信息https://gavindraper.com/2011/03/01/retrieving-accurate-cpu-usage-in-c/