11

我想在我的项目中拥有当前的 CPU 利用率

namespace Monitoring_Tool
{
    public partial class ajaxExecute : System.Web.UI.Page
    {
        private PerformanceCounter theCPUCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
        private PerformanceCounter theMemCounter = new PerformanceCounter("Memory", "Available MBytes");

        protected void Page_Load(object sender, EventArgs e)
        {
            float cpuUsage = 0.00F;

            cpuUsage = this.theCPUCounter.NextValue();
        }
    }
}

当我调试我的项目时, in 的值cpuUsage正在显示0.00,但是当我这样做QuickWatch时,this.theCPUCounter.NextValue();它正在显示20.6786852.

为什么我不能将它存储在变量中?

4

2 回答 2

11

那是因为您需要NextValue在同一个实例上多次调用PerformanceCounter(所以至少两次)。第一次调用将始终返回 0。

NextValue您可以通过在事件处理程序中调用两次来解决此问题(某种程度上)Page_Load,只存储第二次调用的返回值:

        float cpuUsage = 0.00F;

        this.theCPUCounter.NextValue();
        cpuUsage = this.theCPUCounter.NextValue();

它显示在调试器的 QuickWatch 中的原因可能只是因为它被(隐式)多次调用(一次由程序调用,一次由调试器调用 QuickWatch 值)。

更新到上面的“排序”:

正如其他人所提到的,您通常需要在两次调用之间休眠一段时间,以实际观察导致“可测量”差异的 CPU 负载差异。休眠 1 秒通常可以解决问题,但在加载页面时可能不是可接受的延迟。

你真正想要做的是提供一个后台线程来重复查询这个性能计数器,在这之间休眠几秒钟。并将结果存储在某处。从您Page_Load或其他事件/函数中查询(最后一个)值。当然,所有这些都具有针对数据竞争的必要锁定。关于这个指针,它将尽可能准确。

由于您显然使用的是 ASP.NET,因此您必须小心使用此类后台线程。我不是 ASP.NET 专家,但据此应该是可能的,即使线程(以及它所做的性能计数器读数)将被回收,当您的应用程序域/Web 应用程序是。但是,对于这种不应该成为问题的功能。

于 2013-08-23T09:02:25.933 回答
10

它是一个性能计数器,很大程度上取决于您阅读它的时间处理器内核要么正在执行代码,要么以“100%”的速度全速运行。或者完全关闭,由 HALT 指令停止。“% Processor Time”计数器告诉您,自从您上次检查它以来,它一直在执行代码的时间百分比。

因此,如果您在采样之间等待足够长的时间,您只会获得有意义的值。一秒钟是样板文件,这就是您在 Perfmon.exe 和 Taskmgr.exe 中看到的内容。间隔越短,数字越不准确。它开始变化很大,在 0 到 100% 之间跳跃。

所以在页面的 Load 事件中得到 0% 是正常的,它只是初始化计数器来设置间隔的开始。获取下一个样本很困难,您实际上无法在事件处理程序中执行此操作。您必须做一些激烈的事情,例如拥有一个单独的计时器或线程,以一秒的间隔进行采样并使用该值。

于 2013-08-23T09:13:44.740 回答