WPF任务管理器:处理刷新CPU负载值



我目前对c#/wpf(以及一般的编码(有些陌生。我决定开始另一个项目,做一个定制的"任务经理"。

(虽然我使用绑定,但这不是MVVM项目,所以欢迎所有答案(

如果您曾经打开过任务管理器,您就会知道它提供的主要有用工具之一是CPU/RAM/任何用途的更新视图。告诉用户他们正在使用的资源的百分比。

我的问题是没有得到CPU百分比。我不确定如何有效地刷新UI中CPU负载的文本属性。

我的第一个想法是,我应该创建一个后台工作程序(这可能是正确的(来分离线程负载。然而,我似乎无法专注于以有用的方式实现后台工作者的解决方案。

代码目前是以这种方式设置的:

  1. 加载页面时,公共BgWrk会自己创建一个新的实例
  2. 添加运行时要调用的任务
  3. BgWrk已运行
  4. 将生成要调用的方法的新实例
  5. 在主线程上调用Dispatcher来更新UI
  6. Invoke包括在"grabber"的CpuPerUsed的返回值上设置公共字符串PerCpu(绑定在其他类中,使用INotifyPropertyChanged&all(
  7. BgWrk已处理
  8. 程序循环(这很可能是问题所在(。

    private void Grid_Loaded(object sender, RoutedEventArgs e)
    {
    BgWrk = new BackgroundWorker();
    BgWrk.DoWork += new DoWorkEventHandler(BackgroundWorker1_DoWork);
    BgWrk.RunWorkerAsync(); 
    }
    private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
    while (true)
    {
    CpuInfoGrabber grabber = new CpuInfoGrabber();
    Application.Current.Dispatcher.Invoke(new Action (() => Bnd.PerCpu = grabber.CpuPerUsed()));
    BgWrk.Dispose();
    }
    }
    

同样,代码是有效的,但由于检索所有数据的负载,速度有点慢。任何关于如何做好这项工作的建议都将不胜感激!

感谢

您可以使用计时器定期轮询CPU使用情况,而不是循环。

class Test
{
private System.Timers.Timer _timer;
public Test( )
{
_timer = new System.Timers.Timer
{
// Interval set to 1 millisecond.
Interval = 1,
AutoReset = true,                
};
_timer.Elapsed += _timer_Elapsed;
_timer.Enabled = true;
_timer.Start( );
}
private void _timer_Elapsed( object sender, System.Timers.ElapsedEventArgs e )
{
// This handler is not executed on the gui thread so
// you'll have to marshal the call to the gui thread
// and then update your property.
var grabber = new CpuInfoGrabber();
var data = grabber.CpuPerUsed();
Application.Current.Dispatcher.Invoke( ( ) => Bnd.PerCpu = data );
}
}

在您的情况下,我会使用Task.Run而不是BackgroundWorker

private void Grid_Loaded(object sender, RoutedEventArgs e)
{
//Keep it running for 5 minutes
CancellationTokenSource cts = new CancellationTokenSource(new TimeSpan(hours: 0, minutes: 5, seconds: 0));
//Keep it running until user closes the app
//CancellationTokenSource cts = new CancellationTokenSource();
//Go to a different thread
Task.Run(() =>
{
//Some dummy variable
long millisecondsSlept = 0;
//Make sure cancellation not requested
while (!cts.Token.IsCancellationRequested)
{
//Some heavy operation here
Thread.Sleep(500);
millisecondsSlept += 500;
//Update UI with the results of the heavy operation
Application.Current.Dispatcher.Invoke(() => txtCpu.Text = millisecondsSlept.ToString());
}
}, cts.Token);
}

最新更新