WPF BackGroundWorker Progress изменил не обновлять текстовый блок - PullRequest
1 голос
/ 31 мая 2010

У меня есть метод ниже, который, кажется, ведет себя странно. ProgressChanged и RunWorkerCompleted, кажется, обновляются одновременно. Если я закомментирую код 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 ]

1 голос
/ 10 февраля 2011

На самом деле дело в том, что для 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";
}

Для этого прочитайте руководство о Dispatcher и DispatcherObject.

0 голосов
/ 31 мая 2010

Я бы посоветовал вам обернуть это в 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, так как при попытке обновить * 1009 может быть ошибка многопоточности * сам из класса фонового рабочего.

...