views:

186

answers:

1

I have the method below that seems to behaving strangely. The ProgressChanged and RunWorkerCompleted seem to be updating themselves at the same time. If I comment out the RunWorkerCompleted code which updates the Textblock I see the ProgressChanged taking effect after the data is transferred. What am i doing wrong here? I obviously want the textblock to show I'm getting data, then change when I have finished getting the data.

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();
}
A: 

I would suggest you wrap this up in a try{...}catch block... and a using clause, as shown below

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 */
   }
}

If there is no exception thrown, perhaps using an BeginInvoke method of the txtMessages class as shown above in the RunWorkerCompleted event handler, as there may be a cross-threading error when trying to update the txtMessages itself from the backgroundworker class.

tommieb75
I tried that and no exceptions are being thrown. Incidentaly, I don't see the "InvokeRequired" as a property of the TextBlock class. After being up all night on this I think I better just use straight dispatchers and invoke so I can get a life.
Sam