title: How to correctly implement a BackgroundWorker with ProgressBar updates?
body: <p><strong><em>-Updated--14/10</em></strong> also asked this <a href="https://stackoverflow.com/questions/19362040/closing-a-wpf-window-created-on-a-different-thread-from-the-background-worker-wo">question</a></p>
  
  <p>To give some clear idea of what is going on and taking into account the comments and from this article <a href="http://www.codeproject.com/Articles/449594/Progress-Bars-Threads-Windows-Forms-and-You" rel="nofollow noreferrer">here</a></p>
  
  <p>What I really want to do now is invoke a new form with a progress bar on it and have that run and animate whilst my back ground thread runs my long process to the database and then invoke a close form event</p>
  
  <p>The background worker is set up here</p>
  
  <pre><code> public partial class MainWindow : Window
  {
      //Declare background workers
      BackgroundWorker bw = new BackgroundWorker();
      BackgroundWorker bwLoadCSV = new BackgroundWorker();
      BackgroundWorker bwProgressBar = new BackgroundWorker();
  </code></pre>
  
  <p>Then delegates added here</p>
  
  <pre><code>  public MainWindow()
      {
          bwLoadCSV.WorkerReportsProgress = true;
          bwLoadCSV.WorkerSupportsCancellation = true;
          bwLoadCSV.DoWork += new DoWorkEventHandler(bwLoadCSV_DoWork);
          bwLoadCSV.ProgressChanged += new ProgressChangedEventHandler(bwLoadCSV_ProgressChanged);
          bwLoadCSV.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwLoadCSV_RunWorkerCompleted);
  </code></pre>
  
  <p>The call is made here from the main window class</p>
  
  <pre><code>  private void CSV_Load_Click(object sender, RoutedEventArgs e)
      ///Function to read csv into datagrid
      ///
      {
          //Turn Cursor to wait
          System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
  
          //Test connection to sql server
          if (CHHoursDataProvider.IsDatabaseOnline() == false)
          {
              System.Windows.Forms.MessageBox.Show("Can not establish contact with sql server" + "\n" + "Contact IT", "Connection Error");
              //Set UI picture
              return;
          }
          //Set a control to update the user here
          tbLoadDgStat.Visibility = Visibility.Visible;
  
          tbLoadDgStat.Text = "Getting data templete from Database...";
          string FilePath = txFilePath.Text;
          if (bwLoadCSV.IsBusy != true)
          {
              //load the context object with parameters for Background worker
              bwCSVLoadContext Context = new bwCSVLoadContext();
              Context.Site = cBChSite.Text;
              Context.FilePath = txFilePath.Text;
              Context.FileName = fileTest;
              Context.Wageyear = cbWageYear.Text;
              Context.Startdate = ((DateTime)dpStartDate.SelectedDate);
              Context.Enddate = ((DateTime)dpEndDate.SelectedDate);
  
              bwLoadCSV.RunWorkerAsync(Context);                
  
          }
  </code></pre>
  
  <p>The background worker do work is</p>
  
  <pre><code>private void bwLoadCSV_DoWork(object sender, DoWorkEventArgs e)
      {
          BackgroundWorker worker = sender as BackgroundWorker;
  
          bwCSVLoadContext Context = e.Argument as bwCSVLoadContext;
  
  
          worker.ReportProgress((10));
          if ((worker.CancellationPending == true))
          {
              e.Cancel = true;
  
          }
          else
          {
              // Perform a time consuming operation and report progress load csv into datagrid.
  </code></pre>
  
  <p>To report the background work I do this. This is where I am trying to load a new form call ProgressDialog which has a progress bar on it, which I am try set to Indeterminable so it just "swishes" across my ProgressDialoge form to show the user something is still going on. I have used the reporter part of the background work because I believe it has access to the main window thread and I am hoping that the invoke method is then called from the main window thread, but I am not really sure</p>
  
  <p>Here is the reporter</p>
  
  <pre><code> private void bwLoadCSV_ProgressChanged(object sender, ProgressChangedEventArgs e)
  
      {
  
  
          this.Dispatcher.Invoke((MethodInvoker)delegate { tbLoadDgStat.Visibility = Visibility.Visible; });
          //tbLoadDgStat.Visibility = Visibility.Visible;
  
  
          //this.progressBar1.Value = e.ProgressPercentage;//This works but pauses on long steps
          if (e.ProgressPercentage == 10)
          {
              //Try to open a new form with a class ProgressDialog and set the progressbar
              // on the frm to IsIndeterminate=true
              //THIS IS NOT WORKING
              this.Dispatcher.BeginInvoke (new Action(() =&gt;
                {  ProgressDialog progressDialog = new ProgressDialog();
                  progressDialog.SetIndeterminate(true);
              }));
  
               //this updates the main form OK
               this.Dispatcher.Invoke((MethodInvoker)delegate { tbLoadDgStat.Text = "Getting data templete from Database..."; });
  
          }
          else if (e.ProgressPercentage == 20)
          {
  
              this.Dispatcher.Invoke((MethodInvoker)delegate { tbLoadDgStat.Text = "Data template retrieved..."; });
  
          }
          else
          {
  
              if (e.ProgressPercentage % 10 == 0)
              {
                  this.Dispatcher.Invoke((MethodInvoker)delegate { tbLoadDgStat.Text = "Adding Data..." + e.ProgressPercentage.ToString() + "%"; });
              }
          }
  </code></pre>
  
  <p>Lastly the xaml for the ProgressDialog Form and it's class</p>
  
  <pre><code>&lt;Window x:Class="Test_Read_CSV.ProgressDialog"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Progress Dialog" Height="115" Width="306" Name="ProgressPopup"&gt;
  &lt;Grid&gt;
      &lt;ProgressBar Height="31" HorizontalAlignment="Left" Margin="12,33,0,0" Name="progressBar1" VerticalAlignment="Top" Width="250" /&gt;
      &lt;TextBox Height="23" HorizontalAlignment="Left" Margin="7,4,0,0" Name="tbEvent" VerticalAlignment="Top" Width="254" IsReadOnly="True" IsEnabled="False" /&gt;
  &lt;/Grid&gt;
  </code></pre>
  
  <p></p>
  
  <p>class</p>
  
  <pre><code>/// &lt;summary&gt;
  /// Interaction logic for ProgressDialog.xaml
  /// &lt;/summary&gt;
  public partial class ProgressDialog : Window
  {
      public ProgressDialog()
      {
          WindowStartupLocation = WindowStartupLocation.CenterScreen;
          InitializeComponent();
      }
  
      public ProgressDialog(String Purpose)
      {
          InitializeComponent();
          tbEvent.Text = Purpose;
          WindowStartupLocation = WindowStartupLocation.CenterScreen;
  
      }
      public void UpdateProgress(int progress)
      {
          progressBar1.Dispatcher.BeginInvoke(
              new Action(() =&gt;
              {
                  progressBar1.Value = progress;
              }
          ));
      }
  
      public void SetIndeterminate(bool isIndeterminate)
      {
          progressBar1.Dispatcher.BeginInvoke(
              new Action(() =&gt;
              {
                  if (isIndeterminate)
                  {
                      progressBar1.IsIndeterminate = true;
                  }
                  else
                  {
                      progressBar1.IsIndeterminate = false;
                  }
              }
          ));
      }
  }
  
  }
  </code></pre>
  
  <p>I have read and done a number of tutorial on background worker and even some on threads but can not seem to get the result I want</p>
  
  <p>The idea is I have two long processes where I am either getting a datatable clone from my remote bd or I am updating the db from my wpf application (.net 4). While the process is running I want a progress bar control and to update it, for the obivous reason of making it clear that some work is going on. So I did the usual report progress routines in the background worker and it works....However, in my dowork thread I have this command</p>
  
  <pre><code>CHHoursDataProvider CH = new CHHoursDataProvider();
  oTable = CH.CloneCHHours();
  </code></pre>
  
  <p>this where the communication with db is and this command takes a good 60 - 90 secs on a vpn remote connection so even if I do this</p>
  
  <pre><code>CHHoursDataProvider CH = new CHHoursDataProvider();
  worker.ReportProgress((10));
  oTable = CH.CloneCHHours();
  worker.ReportProgress((20));
  </code></pre>
  
  <p>The main window still looks frozen and like it has crashed!</p>
  
  <p>So all I want to do is at the start of the call to the background work is set a progressbar running and leave it running till the end of the task. This is all I need to do to finish my first ever project and after three days I still can not get my head around it!</p>
  
  <p>So I have tried the follow</p>
  
  <p>In the bw progress changed and in the main window class</p>
  
  <pre><code> this.progressBar2.IsIndeterminate = true;
  </code></pre>
  
  <p>However the animation does not start till the Dowork thread has finished.</p>
  
  <p>I then created another background worker to do update the progressbar2, which linked to a button on the main window was ok, but as soon as I tried to use it from the other background worker or from the main window class did not run till the dowork thread had completed on the first background worker</p>
  
  <p>I then tried to follow a invoke method but REALLY got lost on that!</p>
  
  <p>So can anyone help I can guess it is something to do with threading and working on the wrong thread etc but what I do about it I have no clue. </p>
  
  <p>I can post more code as needed</p>
  
  <p>Ian</p>