【问题标题】:Backgroundworker won't report progress后台工作人员不会报告进度
【发布时间】:2010-10-25 16:03:23
【问题描述】:

我有一个后台工作人员正在运行一个长时间的数据库任务。我想在任务运行时显示进度条。不知何故,后台工作人员不会报告任务的进度。

这就是我所拥有的:

BackgroundWorker _bgwLoadClients;

_bgwLoadClients = new BackgroundWorker();
_bgwLoadClients.WorkerReportsProgress = true;
_bgwLoadClients.DoWork += new DoWorkEventHandler(_bgwLoadClients_DoWork);
_bgwLoadClients.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bgwLoadClients_RunWorkerCompleted);
_bgwLoadClients.ProgressChanged += new ProgressChangedEventHandler(_bgwLoadClients_ProgressChanged);
_bgwLoadClients.RunWorkerAsync(parms);

private void _bgwLoadClients_DoWork(object sender, DoWorkEventArgs e)
{
    DataTable dt = getdate();
    e.Result = dt;
}

void _bgwLoadClients_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

我在 WPF 中这样做,但我想这不会有什么不同。

提前致谢

【问题讨论】:

  • 如果您在输入(或编辑)问题时将代码缩进四个空格,它将像代码一样以缩进和格式显示,而不是混合成一个段落并且难以阅读。
  • 您似乎没有调用 BackgroundWorker 的 .ReportProgress 方法 - 仅仅是因为您向我们展示了一些简化的代码吗?
  • @Mike,我认为这可能是原因而不是过度编辑示例。
  • 我无法调用 ReportProgress 方法,因为我只在 Dowork 方法中做一件事和一件事。我可以在 getdate() 调用之前和之后放置一个 .ReportProgress,但是在调用 getdata() 时进度条永远不会前进..
  • 如果你正在做的事情没有被分成几个步骤,它需要多长时间是确定性的吗?否则,您将无法报告除 0% 或 100% 之外的任何内容。您可能想要使用不确定的进度条。

标签: c# wpf backgroundworker progress


【解决方案1】:

您需要将 DoWork 方法分解为可报告的进度,然后调用 ReportProgress。

以以下为例:

private void Something_DoWork(object sender, DoWorkEventArgs e) 
{
    // If possible, establish how much there is to do
    int totalSteps = EstablishWorkload();

    for ( int i=0; i<totalSteps; i++)
    {
        // Do something...

        // Report progress, hint: sender is your worker
        (sender as BackgroundWorker).ReportProgress((int)(100/totalSteps)*i, null);
    }

}

如果您的工作无法预先确定,请尝试添加您自己的百分比:

private void Something_DoWork(object sender, DoWorkEventArgs e) 
{
    // some work

    (sender as BackgroundWorker).ReportProgress(25, null);

    // some work

    (sender as BackgroundWorker).ReportProgress(50, null);

    // some work

    (sender as BackgroundWorker).ReportProgress(60, null);

    // some work

    (sender as BackgroundWorker).ReportProgress(99, null);
}

【讨论】:

  • 编程不错,数学不好 ;-) (int)(100.0 / totalSteps * i)
【解决方案2】:

在属性窗口或代码中将 backgroundworker 对象的 WorkReportProgress 属性修改为 true

【讨论】:

  • 如果他们从一开始就将其默认为 true,那我真的可以节省 20 分钟!或者当有人调用 ReportProgress 时让它变为真。或者抛出一个更好的异常。谢谢老哥!
【解决方案3】:

您必须手动调用ReportProgress() 来引发ProgressChanged 事件。

【讨论】:

    【解决方案4】:

    您需要在 DoWork 方法中调用 worker.ReportProgress(percentComplete)。 percentComplete 应根据总工作量计算。例如:

    for(int i =0; i != 100; i++) {
        // do something
        worker.ReportProgress(i);
    }
    

    有时很难将作业分成几个块来报告进度。不幸的是 BackgroundWorker 不能解决这个问题,你必须自己做。

    【讨论】:

      【解决方案5】:

      只报告dowork事件的进度

      private void _bgwLoadClients_DoWork(object sender, DoWorkEventArgs e) {
          int progresValue0to100 = 75;
          (sender as System.ComponentModel.BackgroundWorker).ReportProgress(progresValue0to100);
          //do your jobs..
      }
      

      它是这样工作的

      【讨论】:

        【解决方案6】:

        必须通过调用 BackgroundWorker 上的 ReportProgress 方法从 DoWork 事件中发送进度。在您的情况下,您无法报告任何进度,因为所有工作都是在 DoWork 功能之外完成的。您只能在调用 getdate() 之前和之后报告进度,但不能在调用期间报告进度,因为 BackgroundWorker 线程正忙。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-06-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多