首页 >后端开发 >C++ >如何与活跃的背景工作者优雅地关闭表格?

如何与活跃的背景工作者优雅地关闭表格?

Patricia Arquette
Patricia Arquette原创
2025-01-31 17:01:10845浏览

How to Gracefully Close a Form with an Active BackgroundWorker?

优雅关闭带有活动 BackgroundWorker 的窗体

当窗体初始化一个更新窗体 UI 的 BackgroundWorker 时,关闭窗体而不遇到异常或死锁可能会变得棘手。此问题突出了在窗体的 Closing 事件中尝试停止 BackgroundWorker 时面临的挑战。

问题:

  1. 在 HandleClosingEvent 中使用 bgWorker.CancelAsync() 取消 BackgroundWorker 可能会在调用 Invoke() 时导致 ObjectDisposedException
  2. 在 HandleClosingEvent 中等待 BackgroundWorker 完成会导致死锁,因为 Invoke() 不会返回。

解决方案:

避免死锁和异常的安全方法是取消 FormClosing 事件本身。以下步骤概述了该解决方案:

  1. 定义一个 closePending 标志来跟踪用户的关闭请求。
  2. OnFormClosing 覆盖中,检查 BackgroundWorker 是否繁忙。
  3. 如果繁忙,则将 closePending 设置为 true,取消 BackgroundWorker,并通过设置 e.Cancel = true 来阻止窗体关闭。
  4. 在 BackgroundWorker 的 RunWorkerCompleted 事件处理程序中,检查是否设置了 closePending。如果为 true,则关闭窗体。
  5. 关闭操作后,将 closePending 标志重置为 false。

示例代码:

<code class="language-csharp">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;
    // 其他操作...
}</code>

使用这种方法,即使 BackgroundWorker 正在积极更新 UI,也可以优雅地关闭窗体,而不会出现异常或死锁。

以上是如何与活跃的背景工作者优雅地关闭表格?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn