如何获取进程列表并将其存储在ListBox中,每次更改进程列表时都要更改ListBox

时间:2018-11-24 07:17:30

标签: c# winforms process listbox

在这种情况下,我正在尝试实现类似于任务管理器的效果。我有一个窗体(称为MainForm),其中有一个ListBox(称为listBox1),我想在其中存储进程。每次进程列表更改时,我都希望ListBox自动更新以包括新的进程列表(我不想按下按钮来更新它)。

到目前为止,我已经尝试过:

  • 线程化(我或者收到“跨线程操作无效:控件从创建该线程的线程之外的其他线程访问”错误,或者它什么都不做或没有工作
  • 计时器(这些按钮根本不起作用)
  • do-while循环(这些会冻结Form或使其根本无法加载)
  • BindedLists(这些实际上更新了ListBox,但它们有一半时间不起作用)
  • 事件(这些根本不起作用)
  • 此站点上类似问题的解决方案
  • 子例程(与do-while循环相同)
  • 递归函数调用(与do-while循环相同)
  • 创建进程列表的多个不同副本,并检测何时更改(这太复杂,混乱和效率低下)
  • ListBox.BeginUpdate()和ListBox.EndUpdate()(这些根本不起作用)
  • ListBox.Refresh()和ListBox.Update()(不是很有用)

这是我的代码(由于我在技术上要求代码,因此这实际上不是必需的):

Process[] processes = Process.GetProcesses();
foreach (Process proc in processes) {
    if (proc.MainWindowTitle.Length > 0)
    {
        listBox1.Items.Add(item);
    }
}

谢谢!

编辑:有些人建议我回顾一下Timer方法。这是该代码:

// For this example, I will just set it to update every 1/4th of a second.
public static System.Timers.Timer aTimer = new System.Timers.Timer(250);
public MainForm {
    InitializeComponent(); // Create the form
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
    aTimer.Enabled = true;
}

public static void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e) {
    UpdateList();
}

public void UpdateList {
    listBox1.Items.Clear();
    Process[] processes = Process.GetProcesses();
    foreach (Process proc in processes) {
        if (proc.MainWindowTitle.Length > 0)
        {
            listBox1.Items.Add(item);
        }
    }
}

我还尝试了其他各种方法,例如停止计时器然后再次设置它,但是它们根本不影响它。奇怪的是,我已经尝试过的大多数技术确实可以在控制台模式下工作(尤其是线程和计时器。它们似乎在WinForms中不起作用)。

1 个答案:

答案 0 :(得分:0)

在WinForms项目中,基本上是加载窗体/控件并将控件交还给OS。您的程序在发生诸如鼠标单击,按键或计时器事件之类的事情之前,不会在“主”线程中执行任何操作。

因此,在“主”线程上的while循环中,您没有将控制权交还给操作系统,并且您的应用程序似乎挂起了,因为您没有给操作系统提供重新绘制窗口的机会

如果您使用的是System.Threading.TimerSystem.Timers.Timer或正在盯着自己的线程,则代码将不会在“主”线程上运行,并且您将无法直接更新控件。不过,您可以使用Control.BeginInvoke为其排队消息。

在主线程上一个System.Windows.Forms.Timer “打勾”。我建议您考虑使用那个。