优雅关闭带有活动 BackgroundWorker 的窗体
当窗体初始化一个更新窗体 UI 的 BackgroundWorker 时,关闭窗体而不遇到异常或死锁可能会变得棘手。此问题突出了在窗体的 Closing 事件中尝试停止 BackgroundWorker 时面临的挑战。
问题:
bgWorker.CancelAsync()
取消 BackgroundWorker 可能会在调用 Invoke()
时导致 ObjectDisposedException
。Invoke()
不会返回。解决方案:
避免死锁和异常的安全方法是取消 FormClosing 事件本身。以下步骤概述了该解决方案:
closePending
标志来跟踪用户的关闭请求。OnFormClosing
覆盖中,检查 BackgroundWorker 是否繁忙。closePending
设置为 true,取消 BackgroundWorker,并通过设置 e.Cancel = true
来阻止窗体关闭。RunWorkerCompleted
事件处理程序中,检查是否设置了 closePending
。如果为 true,则关闭窗体。closePending
标志重置为 false。示例代码:
private bool closePending; protected override void OnFormClosing(FormClosingEventArgs e) { if (backgroundWorker1.IsBusy) { closePending = true; backgroundWorker1.CancelAsync(); e.Cancel = true; this.Enabled = false; // 或 this.Hide() return; } base.OnFormClosing(e); } void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (closePending) this.Close(); closePending = false; // 其他操作... }
使用这种方法,即使 BackgroundWorker 正在积极更新 UI,也可以优雅地关闭窗体,而不会出现异常或死锁。
以上是如何与活跃的背景工作者优雅地关闭表格?的详细内容。更多信息请关注PHP中文网其他相关文章!