填充 DataGridView 后应用程序挂起

发布于 2024-08-13 19:25:56 字数 1906 浏览 2 评论 0原文

我有一个简单的表单,带有两个按钮(开始和停止)和一个 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() 行。当我使用“开始而不调试”运行代码时,DataGridView 被填充,但表单随后立即冻结。 我该如何处理这个问题? (如果这还不够,我很抱歉 - 如果有必要,我愿意提供更多信息,但是,正如您可能已经注意到的那样,我在 C# 或 Visual Studio 方面没有太多经验)。

I have a simple form with two buttons (Start and Stop) and a DataGridView. I am trying to populate the DataGridView with the results of a WMI query that enumerates Win32_Process instances and puts all process names in the only column of the DataGridView. The code looks like this:

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();
        }
    }
}

When I run the code using the 'Start Debugging' option it runs fine and populates the DataGridView. One strange thing (at least to me) I noticed is that in the Observer_ObjectReady the Grid.Refresh() line is never reached. When I run the code with 'Start Without Debugging' the DataGridView is populated but the form freezes immediately after that.
How can I deal with this?
(Sorry if this is not enough information - I am willing to provide more if necessary, but, as you might have noticed, I don't have much experience with C# or Visual Studio).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酷炫老祖宗 2024-08-20 19:25:56

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

我刚刚找到这个链接并阅读其源代码可以帮助您实现您的目标: 管理进程在远程机器上

You shouldn't to add a row to your GridView everytime you receive a new entry. You could to load all your processes into a collection and them to bind it to your control.

I just found this link and reading its source code can help you to achieve your objective: Manage Processes on Remote Machine

夜还是长夜 2024-08-20 19:25:56

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

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 事件中将项目添加到集合中,然后在观察者的 Completed 事件中将数据绑定到它们?

第三种可能性可能是未出现的异常和非 UI 线程发出的回调事件的组合——尝试从另一个线程更新 UI 控件是一个很大的禁忌。请参阅“如何进行事件回调进入我的 winforms 线程安全吗?

希望其中的内容对您有所帮助。 :-)

Could it be an Exception is being thrown? Winforms don't just halt execution when an exception is thrown, that method is aborted and an event that you have to manually handle is raised. You'll have to create an exception handler to see them!

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

My guess is that you're getting an exception from something -- it could be that not calling .Connect() on the ManagementScope that you're also not creating is giving you a problem... the following is a portion of what I'm using and it works for me in asynchronous mode. YMMV.

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

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

Also, as Rubens said, the problem may be with the data grid and adding one row at a time. Have you considered adding the items to a collection in the observer's ObjectReady event, and then data binding to them in the observer's Completed event?

A third possibility could be a combination of the exceptions not being surfaced and the callback events being made from a non-UI thread -- Attempting to update UI controls from another thread is a big no-no. See "How do I make event callbacks into my winforms thread safe?"

Hope something there is helpful to you. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文