开发者

Check CPU Usage and log Processes that have up to 30% CPU Usage in Windows

I have 3 relational question:

I want to check cpu usage and write this code:

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

I check CPU usage by queryin WMI for 2 seconds period and log CPU usage in a DataTable.I have two problems:

  1. I used BackGroundWorker and in DoWork I add a new row of my log information to DataTable and in RunWorkerCompleted Event I assign My DataTable to my ListView but wheras my DataTable has rows but my ListView does not show anything.

  2. My CPU usage that quering WMI has differece with "Task Manager".Why?

  3. How to get Process that has Maximum CPU usage using WMI?

thanks

Edit 1)

for No 1 it's enough to refresh items in ListView


Your code has multiple flaws. This isn't perfect (e.g. I'm not using a ListView as you are), but it should give you a starting point.

Primarily, don't update your data source directly within the DoWork event handler.

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

That should help you solve question 1.

Question 2 - I guess this is probably just to do with sampling.

Question 3, not sure. You could easily keep track of the maximum value returned from your worker - that would be your maximum CPU usage.


You shouldn't add a row on another thread. So you need to use the ProgressChanged event to dialog with the other thread:

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

Then when that event fires, add a row:

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

And in dowork, when you want to add a row:

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

You can read about tuples here: Tuple but if your version of the framework is too low, make a custom object instead to hold the information.

The other 2 questions, i'd go with trial and error ;)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜