如何在不冻结UI的情况下连续更新列表

时间:2014-07-16 17:33:18

标签: c# .net winforms visual-studio-2013

好的,我有一个方法可以读取正在运行的进程,过滤器,对它们进行排序,然后在相应的列表框中显示它们的名称(运行进程而不是正在运行的进程)。我正在异步运行此方法,以便GUI可以继续运行,同时进程查看器继续运行,直到程序退出。我使用一个简单的while循环来完成此任务,但该方法似乎没有循环。该方法第一次正常运行,但它不会继续运行,它会在第一次迭代后停止。

如何无限制地循环并继续更新列表框?

这是我的方法

private async void process_viewer()
    { 
        while (true)
        {

        Process[] running_processes = Process.GetProcesses();

            foreach (Process proc in running_processes)
            {
                this.process_list.Add(proc.ProcessName);
            }

            if (this.process_list.Contains("notepad"))
            {
                this.running_list.Add("notepad.exe");
            }
            else
            {
                this.stopped_list.Add("notepad.exe");
            }

            if (this.process_list.Contains("calc"))
            {
                this.running_list.Add("calc.exe");
            }
            else
            {
                this.stopped_list.Add("calc.exe");
            }

            if (this.process_list.Contains("cmd"))
            {
                this.running_list.Add("cmd.exe");
            }
            else
            {
                this.stopped_list.Add("cmd.exe");
            }

            running.SelectionMode = SelectionMode.None;
            stopped.SelectionMode = SelectionMode.None;

            running.DataSource = this.running_list;
            stopped.DataSource = this.stopped_list;

            this.running_list.Clear();
            this.stopped_list.Clear();
            this.process_list.Clear();

            await Task.Delay(500);
        }
    }

1 个答案:

答案 0 :(得分:1)

看来,无论您对数据进行绑定的控制是什么,实际上并不是立即从该数据源读取数据,而是将数据绑定安排在将来的某个时刻发生,之后您将'已经清除了列表,导致控件被绑定到空列表。

首先,这些列表确实没有任何理由成为字段。您应该简单地重新创建在循环的每次迭代中运行或未运行的进程列表(您关心的),将这些结果绑定到您的控件,然后再次循环时不记得任何先前的迭代。< / p>

private static string[] processNamesICareAbout =
    new[] { "notepad", "calc", "cmd" };
private async void process_viewer()
{
    while (true)
    {
        var processes = Process.GetProcesses()
            .Select(process => process.ProcessName);

        running.SelectionMode = SelectionMode.None;
        stopped.SelectionMode = SelectionMode.None;
        running.DataSource = processNamesICareAbout.Intersect(processes).ToList();
        stopped.DataSource = processNamesICareAbout.Except(processes).ToList();

        await Task.Delay(500);
    }
}