如何使用BackgroundWorker更新多个标签?

时间:2012-09-02 12:39:03

标签: c# user-interface backgroundworker

这是Updating a dialog from another form的后续问题(代码和截图可以在那里找到)

为了解决我的GUI挂起问题,我收到了2条建议:

  • 使用Application.DoEvents()

  • 使用BackgroundWorker

DoEvents()方法有效,但有人指出我不应该使用它。实际上,我注意到GUI正确更新但在短时间内没有响应。

这就是我想使用BackgroundWorker并阅读它的原因。

我不明白我将如何实现它,以便它可以用来分别更新我的示例代码中的4个标签。 我想在程序成功完成一项工作时显示进度(并更新4个对话框标签)。尽管BackgroundWorker只有1 DoWork()。我曾尝试使用e.Argument的{​​{1}}来区分不同的更新方法,但尝试失败了。

DoWorkEventArgs

我无法想象有4个BackgroundWorkers可以解决这个非常简单的对话框。

1 个答案:

答案 0 :(得分:1)

据我了解您的问题,您希望让对话框形式告知用户运行应用程序的4个不同方面:

  • 打印状态
  • 档案状态
  • 导入状态
  • archiver status

后台工作者可以用来定期检查每一个。在检查每个操作的状态后,您可以将进度条提前25%(并使用适当的信息更新UI)。

您也可以尝试异步编程 - 即只需启动操作,然后让您的应用程序继续运行。操作完成后,将通知您的应用程序,并可以更新表单上的信息。 根据您使用的.NET框架,您可以使用asyncawait(自.NET 4.5 / C#5以来可用 - async & await on MSDN)或classic approach to asynchronous programming

<小时/> 编辑:

我不确定BackgroundWorker是否是这种情况下的最佳解决方案。我可以想象有类似的东西:

  1. BackhgroundWorker只检查一次 - 即检查打印状态一次,文件状态一次,导入状态一次,归档状态一次。这可能听起来很愚蠢,但它可能是用户行为驱动程序 - 即当用户点击或以任何其他方式调用此机制时显式启动。 ProgressBar可以放在应用程序的statausbar上,这样用户就知道“应用程序实际上正在做某事”。

  2. 以前的方法可能会有所改进 - 你实际上从未在BackgroundWorker中完成你的工作 - 而是在你的main方法中你只有一个无限循环。这将允许您定期检查事物。在这种方法中,没有必要增加进度。

  3. 第二种方法的样本:

    private void bg_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;
        for (int i = 1; i <= 10; i++)
        {
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
                break;
            }
            else
            {
                CheckPrintingStatus();
                CheckFileStatus();
                CheckImportStatus();
                CheckArchiverStatus();
                System.Threading.Thread.Sleep(5000); // sleep for 5 seconds
            }
        }
    }
    

    如果此解决方案(第二种方法)比明确创建线程更好,则存在一个问题。您可以考虑创建4个不同的线程,以便每个线程都可以检查其他内容。这在操作系统上会稍微重一些,但另一方面,您可以为每个操作设置不同的休眠时间。

    如果你选择裸线程 - 你可能想要使用ThreadPool而不是明确地创建线程。