简体   繁体   English

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

[英]WPF Task Manager: Handling Refreshing CPU Load Value?

I am currently somewhat new to c#/wpf (and coding in general). 我目前对c#/ wpf(以及一般编码)有些新手。 I decided to start another project, being a custom made "task manager" of sorts. 我决定开始另一个项目,成为一个定制的“任务经理”。

(While I use binding, this is NOT a MVVM project, so all answers welcome) (虽然我使用绑定,但这不是MVVM项目,所以欢迎所有答案)

If you have ever opened task manager, you know that one of the main helpful tools it provides is a updating view of CPU/RAM/Whatever usage. 如果您曾经打开任务管理器,您知道它提供的主要有用工具之一是CPU / RAM /无论用法的更新视图。 Telling the user what percent of the resource they are using. 告诉用户他们正在使用的资源百分比。

My problem is not getting the CPU percentage. 我的问题是没有获得CPU百分比。 I am unsure on how to refresh the text property for CPU load in the UI efficiently. 我不确定如何有效地刷新UI中的CPU负载的文本属性。

My first thought was that I should create a Background worker (which is probably correct) to separate the thread loads. 我的第一个想法是我应该创建一个后台工作程序(可能是正确的)来分隔线程负载。 However, I can't seem to wrap my mind on the solution to implement the background workers in a useful way. 但是,我似乎无法将注意力集中在以有用的方式实现后台工作程序的解决方案上。

The code is currently set up in this fashion: 代码目前以这种方式设置:

  1. When page is loaded, public BgWrk creates a new instance of it self. 加载页面时,公共BgWrk会创建一个新的自我实例。
  2. Adds task to be called when ran. 添加要在运行时调用的任务。
  3. BgWrk is ran. BgWrk跑了。
  4. New instance of method to be called is made. 要调用的方法的新实例。
  5. Dispatcher is invoked on main thread to update UI. 在主线程上调用Dispatcher来更新UI。
  6. Invoke consists of setting public string PerCpu (bound in other class, using INotifyPropertyChanged & all) on the return value of "grabber"'s CpuPerUsed. Invoke包括在“grabber”的CpuPerUsed的返回值上设置公共字符串PerCpu(在其他类中绑定,使用INotifyPropertyChanged和all)。
  7. BgWrk disposed. BgWrk弃置了。
  8. Program loops (this is most likely the problem). 程序循环(这很可能是问题)。

     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(); } } 

Again the code works, but it is WAY to slow due to the load of retrieving all of that data. 代码再次起作用,但由于检索所有数据的负担,它的速度很慢。 Any suggestions on how to make this work well are appreciated! 任何关于如何使这项工作很好的建议值得赞赏!

Thanks 谢谢

Instead of looping you could use a timer to periodically poll for the CPU usage. 您可以使用计时器定期轮询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 );
    }
}

I'd use Task.Run instead of a BackgroundWorker in your case: 在你的情况下我会使用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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM