填充DataGridView后应用程序挂起

时间:2009-12-10 21:51:04

标签: c# debugging datagridview wmi

我有一个带有两个按钮(Start和Stop)和一个DataGridView的简单表单。我试图用WMI查询的结果填充DataGridView,该查询枚举Win32_Process实例并将所有进程名称放在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()行。当我使用“Start Without Debugging”运行代码时,将填充DataGridView,但之后表单会立即冻结。 我怎么处理这个? (对不起,如果这不是足够的信息 - 我愿意在必要时提供更多信息,但是,正如您可能已经注意到的那样,我对C#或Visual Studio没有太多经验。)

2 个答案:

答案 0 :(得分:0)

每次收到新条目时,都不应向GridView添加行。您可以将所有流程加载到集合中,然后将它们绑定到您的控件。

我刚刚找到此链接并阅读其源代码可以帮助您实现目标:Manage Processes on Remote Machine

答案 1 :(得分:0)

是不是会抛出异常? Winforms不仅在抛出异常时停止执行,该方法被中止并且引发了您必须手动处理的事件。你必须创建一个异常处理程序才能看到它们!

Application.ThreadException += 
    new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

我的猜测是你从某些东西中得到一个例外 - 可能是因为没有在ManagementScope上调用你也没有创建的.Connect()给你一个问题......以下是一部分我正在使用它,它在异步模式下适用于我。 YMMV。

ManagementScope ms = new ManagementScope(@"\\localhost\root\cimv2\");
ms.Connect();

ManagementObjectSearcher searcher = new ManagementObjectSearcher(ms, query);
searcher.Get(observer);

此外,正如鲁本斯所说,问题可能在于数据网格并且一次添加一行。您是否考虑过在观察者的ObjectReady事件中将项目添加到集合中,然后在观察者的已完成事件中将数据绑定到它们?

第三种可能性可能是未表现的异常和非UI线程发出的回调事件的组合 - 尝试从另一个线程更新UI控件是一个很大的禁忌。请参阅“How do I make event callbacks into my winforms thread safe?

希望对你有所帮助。 : - )