检查CPU使用率并记录Windows中CPU使用率高达30%的进程

时间:2011-07-23 07:37:14

标签: c# wpf multithreading c#-4.0 wmi

我有3个关系问题:

我想查看cpu使用情况并编写此代码:

public partial class MainWindow : Window
{
    private DataTable tbl;
    private int ID;
    private DispatcherTimer Timer;
    private BackgroundWorker bgw;
    public MainWindow()
    {
        InitializeComponent();
        this.listView.DataContext = CreateDataTable();

        Timer = new DispatcherTimer();
        ID = 0;
        Timer.Interval = TimeSpan.FromMilliseconds(2000);
        Timer.Tick += new EventHandler(Timer_Tick);
        bgw = new BackgroundWorker();
        bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
        bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
    }

    void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        this.listView.DataContext = tbl; 
    }

    void bgw_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            ManagementObjectSearcher searcher =
                new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor");

            foreach (ManagementObject queryObj in searcher.Get())
            {
                string s = queryObj["LoadPercentage"].ToString();
                decimal d = decimal.Parse(s);
                tbl.Rows.Add(ID++, DateTime.Now, d);
            } 
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    void Timer_Tick(object sender, EventArgs e)
    {
        if (bgw.IsBusy == false)
        {
            bgw.RunWorkerAsync();
        }
    }

    DataTable CreateDataTable()
    {
        tbl = new DataTable("Customers");

        tbl.Columns.Add("ID", typeof(int));
        tbl.Columns.Add("Time", typeof(DateTime));
        tbl.Columns.Add("Percent", typeof(decimal));

        return tbl;
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        Timer.IsEnabled = true;
    }
}

我通过在WMI中查询2秒来检查CPU使用情况,并在DataTable中记录CPU使用情况。我有两个问题:

  1. 我使用BackGroundWorker并在DoWork我向DataTable添加了一行新的日志信息,并在RunWorkerCompleted事件中我分配了我的DataTable } ListView我的DataTable有行,但我的ListView没有显示任何内容。

  2. 我的CPU使用情况,即查询WMI与“任务管理器”不同。为什么?

  3. 如何使用WMI获取具有最大CPU使用率的进程?

  4. 感谢

    修改1)

    对于1号,它足以刷新ListView中的项目

3 个答案:

答案 0 :(得分:1)

您的代码有多个缺陷。这并不完美(例如我没有像你一样使用ListView),但它应该给你一个起点。

主要是,不要直接在DoWork事件处理程序中更新数据源。

namespace WindowsFormsApplication1
{
    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Management;

    public partial class Form1 : Form
    {
        private Timer Timer = new Timer();
        private BackgroundWorker bgw = new BackgroundWorker();

        public Form1()
        {
            InitializeComponent();

            Timer.Interval = 2000;
            Timer.Tick += Timer_Tick;
            bgw.DoWork += bgw_DoWork;
            bgw.RunWorkerCompleted += bgw_RunWorkerCompleted;
        }

        void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result is Exception)
            {
                Timer.Stop();
                MessageBox.Show(((Exception)e.Result).ToString());
            }
            else
            {
                var result = (UInt16)e.Result;

                listBox1.Items.Add(result.ToString());
            }
        }

        static void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                ManagementObjectSearcher searcher =
                                new ManagementObjectSearcher("root\\CIMV2",
                                "SELECT * FROM Win32_Processor");

                foreach (ManagementObject queryObj in searcher.Get())
                {
                    e.Result = (UInt16)queryObj["LoadPercentage"];
                    return;
                }
            }
            catch (Exception ex)
            {
                e.Result = ex;
            }
        }

        void Timer_Tick(object sender, EventArgs e)
        {
            if (bgw.IsBusy == false)
            {
                bgw.RunWorkerAsync();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Timer.Start();
        }
    }
}

这应该可以帮助您解决问题1.

问题2 - 我想这可能与采样有关。

问题3,不确定。您可以轻松跟踪工作人员返回的最大值 - 这将是您的最大CPU使用率。

答案 1 :(得分:1)

此外,您可能想要检查此项目: How to get CPU usage of processes and threads

答案 2 :(得分:0)

您不应该在另一个线程上添加行。因此,您需要使用ProgressChanged事件与另一个线程对话:

bgw.ProgressChanged += new ProgressChangedEventHandler(bgw_ProgressChanged);
bgw.WorkerReportsProgress = true;

然后当该事件触发时,添加一行:

void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Tuple<int, DateTime, decimal> rowToAdd = e.UserState as Tuple<int, DateTime, decimal>;
            listBox1.Items.Add(rowToAdd.Item1, rowToAdd.Item2, rowToAdd.Item3);
        }

在dowork中,当你想添加一行时:

void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker _bgw = sender as BackgroundWorker;
            _bgw.ReportProgress(0, new Tuple<int, DateTime, decimal>(ID++, DateTime.Now, d));
        }        

您可以在此处阅读有关元组的信息:Tuple但如果您的框架版本太低,请改为创建自定义对象以保存信息。

其他两个问题,我会试错;)