C# 填充DataGridView后,应用程序挂起
我有一个简单的表单,有两个按钮Start和Stop,还有一个DataGridView。我试图用WMI查询的结果填充DataGridView,该查询枚举Win32_进程实例,并将所有进程名称放在DataGridView的唯一列中。代码如下所示:C# 填充DataGridView后,应用程序挂起,c#,debugging,datagridview,wmi,C#,Debugging,Datagridview,Wmi,我有一个简单的表单,有两个按钮Start和Stop,还有一个DataGridView。我试图用WMI查询的结果填充DataGridView,该查询枚举Win32_进程实例,并将所有进程名称放在DataGridView的唯一列中。代码如下所示: using System; using System.Management; using System.Windows.Forms; namespace WindowsFormsApplication10 { public partial cla
using System;
using System.Management;
using System.Windows.Forms;
namespace WindowsFormsApplication10
{
public partial class Form1 : Form
{
ManagementObjectSearcher Searcher =
new ManagementObjectSearcher();
SelectQuery Query = new SelectQuery();
ManagementOperationObserver Observer =
new ManagementOperationObserver();
public Form1()
{
InitializeComponent();
Observer.Completed +=
new CompletedEventHandler(Observer_Completed);
Observer.ObjectReady +=
new ObjectReadyEventHandler(Observer_ObjectReady);
Grid.ColumnCount = 1;
Grid.Columns[0].Name = "Name";
}
private void Start_Click(object sender, EventArgs e)
{
Query.QueryString = "Select * From Win32_Process";
Searcher.Query = Query;
Searcher.Get(Observer);
}
private void Observer_Completed
(object sender, CompletedEventArgs e)
{
Grid.Refresh();
}
private void Observer_ObjectReady
(object sender, ObjectReadyEventArgs e)
{
string [] row = new string []
{e.NewObject["Name"].ToString()};
Grid.Rows.Add(row);
Grid.Refresh();
}
private void stop_Click(object sender, EventArgs e)
{
Observer.Cancel();
}
}
}
当我使用“开始调试”选项运行代码时,它运行良好并填充DataGridView。至少对我来说,我注意到一件奇怪的事情是,在Observer_ObjectReady中,从未到达Grid.Refresh行。当我使用“启动而不调试”运行代码时,DataGridView会被填充,但表单会立即冻结。
我该怎么处理?
抱歉,如果这还不够,我愿意在必要时提供更多信息,但是,正如您可能已经注意到的,我对C或Visual Studio没有太多经验。您不应该每次收到新条目时都向GridView添加一行。您可以将所有进程加载到一个集合中,并将它们绑定到控件
我刚刚发现了这个链接,阅读它的源代码可以帮助您实现您的目标:是否抛出异常?Winforms不仅在抛出异常时停止执行,还会中止该方法并引发您必须手动处理的事件。您必须创建一个异常处理程序才能看到它们
Application.ThreadException +=
new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
我的猜测是,您遇到了某个异常-可能是因为您没有打电话。您也没有创建的ManagementScope上的连接给您带来了问题。。。下面是我正在使用的内容的一部分,它在异步模式下对我有效。YMMV
ManagementScope ms = new ManagementScope(@"\\localhost\root\cimv2\");
ms.Connect();
ManagementObjectSearcher searcher = new ManagementObjectSearcher(ms, query);
searcher.Get(observer);
此外,正如鲁本斯所说,问题可能在于数据网格和一次添加一行。您是否考虑过在观察者的ObjectReady事件中将这些项添加到集合中,然后在观察者的Completed事件中将数据绑定到它们
第三种可能性可能是未出现的异常和从非UI线程生成的回调事件的组合—尝试从另一个线程更新UI控件是一个很大的禁忌。请参阅
希望那里有些东西对你有帮助- 谢谢你的回答。该应用程序使用同步枚举,我也能够以这种方式工作。我的问题是,在枚举诸如CIM_数据文件或Win32_目录之类的类时可能需要很多时间。这就是我尝试使用ManagementOperationObserver.ObjectReady事件使用异步枚举的原因,但我无法使其工作-应用程序冻结。是否需要显示所有数据?你能把它分页吗?有时我需要显示所有的数据。同步枚举运行良好,但对于Cim_数据文件,异步枚举将是正确的选择。我已经能够使用相同的异步代码并将数据发送到RichTextBox,但我也希望能够填充DataGridView。我想这与DataGridView有关,但我感到困惑,因为我没有得到任何异常,应用程序只是冻结,而当我用RichTextBox替换DataGridView并添加Observer_ObjectReady中的文本行时,相同的应用程序工作正常。