我在 WinForm 上有一个计时器,它在表单加载时启动:
private void MainForm_Load(object sender, EventArgs e)
{
Action action = () => lblTime.Text = DateTime.Now.ToLongTimeString();
Task task = new Task(() => {
while (true)
{
Invoke(action);
Task.Delay(1000);
}
});
task.Start();
}
问题是当我在 VS 中以调试模式启动应用程序并关闭它时。我得到一个 ObjectDisposedException,它指出我的表单已经被处理。
我尝试通过以下方式修复它:
private bool _runningTimer = true;
public MainForm()
{
InitializeComponent();
// ...
FormClosing += MainForm_FormClosing;
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
_runningTimer = false;
}
private void MainForm_Load(object sender, EventArgs e)
{
Action action = () => lblTime.Text = DateTime.Now.ToLongTimeString();
Task task = new Task(() => {
while (_runningTimer)
{
Invoke(action);
Task.Delay(1000);
}
});
task.Start();
}
但问题仍然存在。我在这里做错了什么?
更新:我知道 WinForms 有一个标准计时器,它在多线程环境中运行良好。我只是想知道如何让它更好地理解如何处理竞争条件。这种计时器只是一个例子,它可能是另一个需要更新 GUI 的进程。
更新 2:按照Hans Passant和Inigmativity 的答案,我来到了该代码:
private void MainForm_Load(object sender, EventArgs e)
{
Action action = () => { lblTime.Text = DateTime.Now.ToLongTimeString(); };
Task task = new Task(async () => {
while (!IsDisposed)
{
Invoke(action);
await Task.Delay(1000);
}
});
task.Start();
}
但无论如何,如果我设置时间间隔,例如 100 毫秒,ObjectDisposedException 仍然会抛出。
这不是现实生活中的例子,我只是在试验它......
小唯快跑啊
幕布斯6054654
相关分类