在这种情况下,我正在尝试实现类似于任务管理器的效果。我有一个窗体(称为MainForm),其中有一个ListBox(称为listBox1),我想在其中存储进程。每次进程列表更改时,我都希望ListBox自动更新以包括新的进程列表(我不想按下按钮来更新它)。
到目前为止,我已经尝试过:
这是我的代码(由于我在技术上要求代码,因此这实际上不是必需的):
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中不起作用)。
答案 0 :(得分:0)
在WinForms项目中,基本上是加载窗体/控件并将控件交还给OS。您的程序在发生诸如鼠标单击,按键或计时器事件之类的事情之前,不会在“主”线程中执行任何操作。
因此,在“主”线程上的while
循环中,您没有将控制权交还给操作系统,并且您的应用程序似乎挂起了,因为您没有给操作系统提供重新绘制窗口的机会
如果您使用的是System.Threading.Timer
,System.Timers.Timer
或正在盯着自己的线程,则代码将不会在“主”线程上运行,并且您将无法直接更新控件。不过,您可以使用Control.BeginInvoke
为其排队消息。
在主线程上一个System.Windows.Forms.Timer
将“打勾”。我建议您考虑使用那个。