C# 填充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

我有一个简单的表单,有两个按钮Start和Stop,还有一个DataGridView。我试图用WMI查询的结果填充DataGridView,该查询枚举Win32_进程实例,并将所有进程名称放在DataGridView的唯一列中。代码如下所示:

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中的文本行时,相同的应用程序工作正常。