在 C# 中异步检索 Cpu 用法
Retrieve Cpu usage asynchronously in C#
我想使用 c# 检索我的系统的 cpu 使用情况。我读到我必须调用方法 NextValue()
然后等待大约一秒钟并再次调用 NextValue()
方法。
我想异步执行以不延迟我的 UI 线程,所以我编写了以下代码
public Task<float> GetCpuPerformanceAsync()
{
return Task.Run(() =>
{
CpuPerformance.NextValue();
Task.Delay(1000);
return CpuPerformance.NextValue();
});
}
这是CpuPerformance
的声明
CpuPerformance = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
第一次调用上面显示的异步方法时 returns 我实际使用 cpu 但是几秒后再次调用它只显示 0 或 100 这不一致使用我的任务管理器中显示的用法
有人可以帮我解决这个问题吗?
不幸的是,dotnetfiddle 不允许我使用 PerformanceCounters,但这应该可以正常工作:
public class Helper // Of course, you do not necessarily need an extra class ...
{
// Lazy Pattern: Will create an instance on first usage.
private static Lazy<PerformanceCounter> CpuPerformance = new Lazy<PerformanceCounter>(() => {
// this will be used as factory to create the instance ...
// 1. create counter
PerformanceCounter pc = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
// "warm up"
pc.NextValue();
Thread.Sleep(1000);
// return ready-to-use instance
return pc;
// ^^ this will be executed only _once_.
});
// Read-Only Property uses Lazy to ensure instance exists, then use it.
public static float CpuTimeInPercent {
get { return CpuPerformance.Value.NextValue(); }
}
}
用法:
Console.WriteLine("Performance: {0}%", Helper.CpuTimeInPercent);
这是使用他们提出的技术替代@Fildor 的答案,但它避免了在第一次访问 CpuTimeInPercent
时让线程休眠。
public static class Helper
{
private static readonly Task<PerformanceCounter> performanceCounter = GetCounter();
private static async Task<PerformanceCounter> GetCounter()
{
PerformanceCounter pc = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
// "warm up"
pc.NextValue();
await Task.Delay(1000);
// return ready-to-use instance
return pc;
}
public static async Task<float> GetCpuTimeInPercentAsync()
{
var counter = await performanceCounter;
return counter.NextValue();
}
}
这将在第一次执行 performanceCounter
之前的某个时刻开始执行 GetCounter()
(可能是在加载程序集时,也可能是在调用 GetCounter()
时) ,运行时在这里有很大的自由度)。如果您在它进行预热时调用 GetCpuTimeInPercentAsync
,那么它会等到它完成后再获取 CPU 用法。如果您随后调用它,或者在它完成预热后调用它,那么它将 return 立即使用 CPU。
我想使用 c# 检索我的系统的 cpu 使用情况。我读到我必须调用方法 NextValue()
然后等待大约一秒钟并再次调用 NextValue()
方法。
我想异步执行以不延迟我的 UI 线程,所以我编写了以下代码
public Task<float> GetCpuPerformanceAsync()
{
return Task.Run(() =>
{
CpuPerformance.NextValue();
Task.Delay(1000);
return CpuPerformance.NextValue();
});
}
这是CpuPerformance
CpuPerformance = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
第一次调用上面显示的异步方法时 returns 我实际使用 cpu 但是几秒后再次调用它只显示 0 或 100 这不一致使用我的任务管理器中显示的用法
有人可以帮我解决这个问题吗?
不幸的是,dotnetfiddle 不允许我使用 PerformanceCounters,但这应该可以正常工作:
public class Helper // Of course, you do not necessarily need an extra class ...
{
// Lazy Pattern: Will create an instance on first usage.
private static Lazy<PerformanceCounter> CpuPerformance = new Lazy<PerformanceCounter>(() => {
// this will be used as factory to create the instance ...
// 1. create counter
PerformanceCounter pc = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
// "warm up"
pc.NextValue();
Thread.Sleep(1000);
// return ready-to-use instance
return pc;
// ^^ this will be executed only _once_.
});
// Read-Only Property uses Lazy to ensure instance exists, then use it.
public static float CpuTimeInPercent {
get { return CpuPerformance.Value.NextValue(); }
}
}
用法:
Console.WriteLine("Performance: {0}%", Helper.CpuTimeInPercent);
这是使用他们提出的技术替代@Fildor 的答案,但它避免了在第一次访问 CpuTimeInPercent
时让线程休眠。
public static class Helper
{
private static readonly Task<PerformanceCounter> performanceCounter = GetCounter();
private static async Task<PerformanceCounter> GetCounter()
{
PerformanceCounter pc = new PerformanceCounter("Processor Information", "% Processor Time", "_Total");
// "warm up"
pc.NextValue();
await Task.Delay(1000);
// return ready-to-use instance
return pc;
}
public static async Task<float> GetCpuTimeInPercentAsync()
{
var counter = await performanceCounter;
return counter.NextValue();
}
}
这将在第一次执行 performanceCounter
之前的某个时刻开始执行 GetCounter()
(可能是在加载程序集时,也可能是在调用 GetCounter()
时) ,运行时在这里有很大的自由度)。如果您在它进行预热时调用 GetCpuTimeInPercentAsync
,那么它会等到它完成后再获取 CPU 用法。如果您随后调用它,或者在它完成预热后调用它,那么它将 return 立即使用 CPU。