WPF BackGroundWorker ProgressChanged不更新文本块

时间:2010-05-31 09:57:58

标签: wpf backgroundworker

我有下面的方法似乎表现得很奇怪。 ProgressChangedRunWorkerCompleted似乎同时更新了自己。如果我注释掉更新文本块的RunWorkerCompleted代码,我会看到ProgressChanged在传输数据后生效。我在这做错了什么?我显然希望文本块显示我正在获取数据,然后在我获取数据后进行更改。

public void GetAppointmentsBackground()
{
   System.Windows.Threading.Dispatcher webServiceDispatcher = this.Dispatcher;
   worker = new BackgroundWorker();
   worker.WorkerReportsProgress = true;
   worker.DoWork += delegate(object sender, DoWorkEventArgs args)
   {
     GetAppointmentsForDayDelegate getAppt = new GetAppointmentsForDayDelegate(GetAppointmentsForDay);
     webServiceDispatcher.BeginInvoke(getAppt);
     (sender as BackgroundWorker).ReportProgress(25);
   };

   worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
   {
     txtMessages.Text = "Contacting Server";
   };

   worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
   {
     txtMessages.Text = "Completed Successfully";
   };

   worker.RunWorkerAsync();
}

2 个答案:

答案 0 :(得分:1)

事实上,另一个模型用于System.Windows.Controls(与Windows.Forms.Control后代不同)。 我使用了类似的东西:

public delegate void NoArgs();

//...

txtBlock.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, 
    new NoArgs(UpdateTextBlock));

//...

void UpdateTextBlock()
{
    txtBlock.Text = "Contacting Server";
}

阅读有关DispatcherDispatcherObject的手册。

答案 1 :(得分:0)

我建议你将它包装在try{...}catch块...和using子句中,如下所示

public void GetAppointmentsBackground()
{
   System.Windows.Threading.Dispatcher webServiceDispatcher = this.Dispatcher;
   try
   {
     using (BackgroundWorker worker = new BackgroundWorker())
     {
       worker.WorkerReportsProgress = true;
       worker.DoWork += delegate(object sender, DoWorkEventArgs args)
       {
          GetAppointmentsForDayDelegate getAppt = new GetAppointmentsForDayDelegate(GetAppointmentsForDay);
          webServiceDispatcher.BeginInvoke(getAppt);
          (sender as BackgroundWorker).ReportProgress(25);
       };

       worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
       {
          txtMessages.Text = "Contacting Server";
       };

       worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
       {
          if (txtMessages.InvokeRequired)
          {
            txtMessages.BeginInvoke(new MethodInvoker(delegate()
            {
               txtMessages.Text = "Completed Successfully";
            }));
          }
          else
          {
             txtMessages.Text = "Completed Successfully";
          }
       };

       worker.RunWorkerAsync();
     }
   }
   catch(Exception eX)
   {
      /* CHECK HERE TO SEE IF AN EXCEPTION IS THROWN */
   }
}

如果没有抛出异常,可能使用BeginInvoke类的txtMessages方法,如上面RunWorkerCompleted事件处理程序中所示,因为可能存在交叉线程错误尝试从backgroundworker类更新txtMessages本身。