BackgroundWorker的最佳实践

时间:2012-05-16 16:06:59

标签: c# user-interface user-controls backgroundworker

我正在制作我的第一个C#GUI。它使用BackgroundWorker来运行计算量很大的模拟。模拟会定期(通过ProgressChanged事件)报告需要在GUI中显示的大量信息。

GUI分为控件,我希望每个控件都知道如何“自我更新”。

在我的研究中,我找到了很多方法可以做到这一点。

  • 我能想到的是让方法布局到ProgressChanged在GUI的每个部分调用更新方法。
  • 我可以Invalidate GUI并将每个控件更新方法绑定到Validating事件。
  • 我可以将每个控件的更新方法绑定到ProgressChanged事件。
  • 我可以让每个控件实现INotifyPropertyChanged接口(但我怀疑这会起作用)

在所有这些选项中,哪一个是在ProgressChanged事件中更新整个GUI的最佳实践? (或者我是在左外野?)

来自评论:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
  Simulation simulation = new Simulation();
  while(true)
  {
    simulation.RunIteration();
    backgroundWorker.ReportProgress(-1, simulation);
  }
}

2 个答案:

答案 0 :(得分:2)

你不应该做任何特别的事情。

您的ProgressChanged处理程序可以“解压缩”数据并设置控件的相关属性。失效和重新绘制是自动的,它在GUI线程上运行。

你应该小心更新'太频繁'。通常经常取决于数据量,处理程序应在下次更新之前完成。如果没有,建立一些限制机制。

答案 1 :(得分:1)

ProgressBar是我推荐的方法。如果您要发送到GUI的数据是文本,那么您可以使用富文本框或只是常规文本框,并在更改进度条时将文本传递给它:

public void SomeThread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    /* Update progress bar */
    ProgressBar.Value = (e.ProgressPercentage);
    if (e.UserState != null)
    {
        TextBox.Text += (string)e.UserState;
    }
}

对于其他形式的数据,您可以包含一个If语句,当进度条被赋予特定值时,该语句执行X.

但是如果不了解你特别想要做什么,我恐怕无法提供更多的帮助。