【问题标题】:Disposal of a Running BackgroundWorker处理正在运行的 BackgroundWorker
【发布时间】:2014-04-09 21:05:44
【问题描述】:

我已经看到很多关于在 Windows 窗体应用程序中处置 BackgroundWorker 的问题,并且似乎一致认为在大多数情况下不需要手动处置它们。但是,我有一个关于如何处理 BackgroundWorker 实际运行时正在处置的 UserComponent 的问题。 (IsBusy 返回 true)是否应该以任何特定方式处理这种情况?

例如,我有一个用户控件(类似面板的对象),用户可以输入设置信息。它包含一个保存用户配置的 BackgroundWorker。当面板失去焦点(离开事件)时,如果它尚未运行,它会启动 BackgroundWorker,以便在检测到更改时将配置保存到文件。由于离开事件也可能是用户切换到另一个屏幕,因此现在将释放此面板。如果 BackgroundWorker 仍在运行,我是否需要在 UserComponent 本身的 Dispose 方法中进行处理?

【问题讨论】:

    标签: c# winforms backgroundworker idisposable system.componentmodel


    【解决方案1】:

    视情况而定,我们看不到您的代码。首先,您不太可能实现 CancelAsync() ,所以不要为此烦恼。旋转直到 IsBusy 在 Dispose() 方法中返回 false 是一种选择,但请注意死锁。当您为 RunWorkerCompleted 实现事件处理程序时,您肯定会得到一个。你不太可能有一个,所以旋转应该没问题。

    理智的方法是让它运行。用户会很高兴。一些预防措施是必要的:

    • 工作线程应该仍然能够访问控件的属性,即使它已被释放。这通常不是问题,您存储简单支持变量的值,它们不会在控件被释放时变得无效。顺便说一句,测试很容易,但是如果您不确定,那么使用一个简单的类来存储需要保留的值并将其传递给 RunWorkerAsync() 总是安全的。

    • 您需要处理因程序终止而导致工作线程中止的风险。如果在写入文件时发生这种情况,那么文件将被损坏。您可以通过写入 another 文件来解决此问题。并使用 File.Replace() 交换它。一般来说,始终是您在替换文件时应该使用的策略。

    【讨论】:

    • 纺纱的僵局是我害怕的,这也是促使我提出这个问题的原因。 UI 类中的数据在写入配置文件后并不真正需要保留,假设它没有损坏,因为如果在关闭后再次访问它,它将被重新读取以再次填充此面板.
    • 我给出了一个具体的建议来避免它,我建议你使用它。易于测试,只需关闭主窗口并将焦点放在控件上即可。这会触发 Leave,紧随其后的是 Dispose()。确保将 Thread.Sleep(3000) 放入 DoWork。
    • 我一定要去;只是提供一些背景。这可以安全地放置在 RunWorkerCompleted 处理程序中对吗?还是需要在dispose方法中启动?
    • 不,你在 Dispose() 中旋转。正如我所提到的,如果你实现了 RunWorkerCompleted,你就会死锁。我不得不说,您不发布代码会使这变得不必要地困难。请关闭您的问题。
    • 请原谅我要求澄清,不必无礼。我认为这个问题很笼统,不需要 SSCCE,抱歉。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多