我有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使用情况。我有两个问题:
我使用BackGroundWorker
并在DoWork
我向DataTable
添加了一行新的日志信息,并在RunWorkerCompleted
事件中我分配了我的DataTable
} ListView
我的DataTable
有行,但我的ListView
没有显示任何内容。
我的CPU使用情况,即查询WMI与“任务管理器”不同。为什么?
如何使用WMI获取具有最大CPU使用率的进程?
感谢
修改1)
对于1号,它足以刷新ListView中的项目
答案 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但如果您的框架版本太低,请改为创建自定义对象以保存信息。
其他两个问题,我会试错;)