Jed I
Jed I

Reputation: 1018

progress bar not progressing

I have a program which is updating a table in sqlserver, I have a form which I want to show the progress of this, the progress bar is incrementing but this is not being displayed. do i need to use background worker for this? example of what im doing

public void updateTable(string tableName)
{
  // con is an instance of my form to access progressbar
  con.progressBar1.Minimum = 1;
  con.progressBar1.Step = 1;
  string dbQuery = "select summet from someting"

  con.progressBar1.Maximum = address.Tables[0].Rows.Count;
  MessageBox.Show("progress bar max " + con.progressBar1.Maximum);

   foreach (DataRow LonLat in address.Tables[0].Rows)
   {
       con.progressBar1.PerformStep();
       MessageBox.Show(con.progressBar1.Value.ToString()); // this is incrementing
       //plus updating table 

   }


}

Upvotes: 0

Views: 906

Answers (4)

georanto
georanto

Reputation: 131

That happens if we cannot use a BackgroundWorker. I have a form with a progress bar whose only job is to accept a command to PerformStep, from some other form that opens it, and the form must simply do that. Both forms are in the GUI thread. Nevertheless I don't get a consistent behavior from the progressbar. In the code below the progressbar is always one step behind than what its Value Property Signifies:

public partial class Form1 : Form
   {
      private readonly int m_numOfSteps;

      public Form1(int numOfSteps)
      {
         m_numOfSteps = numOfSteps;
         InitializeComponent();
      }

      private void Form1_Load( object sender, EventArgs e )
      {
         progressBar1.Step = (int)Math.Ceiling( 100.0 / m_numOfSteps );
      }

      public void DoStep(string msg)
      {
         progressBar1.PerformStep();
         label1.Text = msg;
         label2.Text = String.Format( "{0}%", progressBar1.Value  );
         label1.Refresh();
         label2.Refresh();
      }
   }

   public partial class Form2 : Form
   {
      public Form2()
      {
         InitializeComponent();
      }

      private void button1_Click( object sender, EventArgs e )
      {
         using( Form1 f = new Form1( 3 ) )
         {
            f.Show();
            f.Refresh();
            Thread.Sleep( 1000 );
            f.DoStep( "AAAA" );
            Thread.Sleep( 1000 );
            f.DoStep( "BBBB" );
            Thread.Sleep( 1000 );
            f.DoStep( "CCCC" );
            Thread.Sleep( 1000 );
         }
      }
   }

Upvotes: 0

Dhaval Patel
Dhaval Patel

Reputation: 7591

yes you have to use background worker

BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += (o, ea) =>
    {
     // your code goes here
       }
 worker.RunWorkerCompleted += (q, ea) =>
    {
      }
 worker.RunWorkerAsync();

Upvotes: 0

nikola-miljkovic
nikola-miljkovic

Reputation: 670

Yes you should use Background Worker, however it might not help, we would need to see bindings and everything else, to use background worker use something like this:

Window.Dispatcher.BeginInvoke((Action)(() =>
        {
            con.progressBar1.PerformStep();
        }

Upvotes: 0

Jorge Córdoba
Jorge Córdoba

Reputation: 52123

Short answer, yes. If you do it from the main thread you won't see the progress bar update.

Long answer:

Whenever you modify the user interface from a piece of your code that's translated into a "message" into the window message queue that will get that message and update the UI accordingly in the main thread.

However, since the main thread is busy handling your piece of code it doesn't have the "time" to actually update the user interface, and only when your process is done, it's free to update the user interface. That's why you see the progress bar going from 0% to 100% without any intermediate steps.

What you should do:

What you wanna do is put the work into a background worker, that way the main thread is free to attend UI update requests... that's, by the way, a standard practice if you wanna keep the UI responsive.

Upvotes: 2

Related Questions