我希望在我的项目中拥有当前的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();
}
}
}
当我调试我的项目时,cpuUsage
中的值显示为0.00
,但当我QuickWatch
this.theCPUCounter.NextValue();
时,它显示20.6786852
。
为什么我不能将它存储在变量中?
答案 0 :(得分:10)
那是因为你需要在同一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专家,但是根据this它应该是可能的,即使你的app域/ web应用程序的线程(和它所做的perf计数器读数)将被回收。但是,对于这种不应成为问题的功能。
答案 1 :(得分:10)
这是一个性能计数器,在你读时非常依赖于。处理器内核要么执行代码,要么以“100%”运行全孔。或者它完全关闭,由HALT指令停止。 “%Processor Time”计数器会告诉您自上次检查以来多少%的时间,它一直在执行代码。
因此,如果您在抽样之间等待足够长的时间,那么您将只获得有意义的值。一秒钟是样板文件,这是你在Perfmon.exe和Taskmgr.exe中看到的。间隔越短,数字越不准确。它开始变化很大,在0到100%之间跳跃。
因此,在页面的Load事件中获得0%是正常的,它只是初始化计数器以设置间隔的开始。获取 next 示例很困难,您无法在事件处理程序中实际执行此操作。你必须做一些激烈的事情,比如让一个单独的计时器或线程以一秒的间隔进行采样并使用该值。