【发布时间】:2013-01-30 23:39:25
【问题描述】:
我有一个程序,它创建一个线程来搜索 WMI(Win32 类)以检查各种系统信息。 现在我为每个搜索创建一个线程,但显然当我使用我的组合框并快速滚动或触发多个线程时,cpu 会出现峰值,即使在关闭表单后,发送的“命令”仍然会发送到 wmi 提供程序,从而导致 cpu飙升了好一阵子……
问题:
在不关闭表单的情况下限制 cpu 使用率/创建的最大线程数以防止 cpu 峰值的最佳方法是什么。 (如果我关闭表单,我可以为 WMI 提供程序进程发送一个终止进程,以便停止它)。
图片:
代码:
namespace Admin_Helper
{
public partial class frmHardwareInformation : Form
{
public frmHardwareInformation()
{
InitializeComponent();
}
string searchQuery;
private void cmbItemList_SelectedIndexChanged(object sender, EventArgs e)
{
var dctPropertyList = new Dictionary<string, string>(); //Store property name/value
searchQuery = cmbItemList.SelectedItem.ToString(); //Search term
new Thread(() => FindWMI(searchQuery, dctPropertyList, lstHwSearchList)).Start(); //Start thread for each search
}
private void FindWMI(string s, Dictionary<string, string> dct, ListView listView)
{
try
{
ManagementObjectSearcher moSearcher = new ManagementObjectSearcher("select * from " + s);
Invoke(new MethodInvoker(() =>
{
listView.Items.Clear(); //Clear items to prevent endless list
}));
foreach (ManagementObject moObject in moSearcher.Get())
{
if (moObject != null) //Gives errors if I don't check for null's..
{
foreach (PropertyData propData in moObject.Properties)
{
if (propData.Value != null && propData.Value.ToString() != "" && propData.Name != null && propData.Name != "") //More prevention of errors..
dct[propData.Name] = propData.Value.ToString();
}
}
}
foreach (KeyValuePair<string, string> listItem in dct)
{
Invoke(new MethodInvoker(() =>
{
listView.Items.Add(listItem.Key).SubItems.Add(listItem.Value);
Application.DoEvents();
}));
}
}
catch (Exception) { } //Mostly catches invalid searches nothing too bad so far
}
}
}
编辑:包含的代码更改
*在表单关闭、创建列表和 1x 调用整个更新时添加了终止进程。
private void FindWMI(string s, Dictionary<string, string> dct, ListView listView)
{
try
{
List<ListViewItem> itemsList = new List<ListViewItem>();
ManagementObjectSearcher moSearcher = new ManagementObjectSearcher("select * from " + s);
Invoke(new MethodInvoker(() =>
{
listView.Items.Clear();
}));
foreach (ManagementObject moObject in moSearcher.Get())
{
if (moObject != null)
{
foreach (PropertyData propData in moObject.Properties)
{
if (propData.Value != null && propData.Value.ToString() != "" && propData.Name != null && propData.Name != "")
dct[propData.Name] = propData.Value.ToString();
}
}
}
foreach (KeyValuePair<string, string> listItem in dct)
{
ListViewItem lstItem = new ListViewItem(listItem.Key);
lstItem.SubItems.Add(listItem.Value);
itemsList.Add(lstItem);
}
Invoke(new MethodInvoker(() =>
{
listView.Items.AddRange(itemsList.ToArray());
}));
}
catch (Exception) { }
}
private void frmHardwareInformation_FormClosed(object sender, FormClosedEventArgs e)
{
foreach (System.Diagnostics.Process myProc in System.Diagnostics.Process.GetProcesses())
{
if (myProc.ProcessName == "WmiPrvSE")
{
myProc.Kill();
}
}
}
【问题讨论】:
-
如果你使用 CPU,是的,使用率会飙升!
-
我知道,我只是想防止 cpu 峰值,当有人滚动组合框时会导致很多新线程 XD 特别是更长的 cpu 峰值 xD
-
另外,您可能不应该调用每个“选定的更改”!启动计时器,当计时器经过时,检查是否相同的项目(如果不是重新启动计时器),如果相同则搜索....或仅搜索“点击”
-
不确定,可能 indexchanged 会更好,嗯,它可能会触发 keychanges...
标签: c# multithreading winforms wmi wmi-query