0

it's my first experience with C#, I'm trying to make a progress bar that increases each second on a value (a part of program, it receives current value from another object and sets it to the progress bar).

My simplified object source:

public delegate void LoadingProgressChanged(int percents);
public event LoadingProgressChanged loadingProgressChanged;

public void Enable()
{
    loadingTimer = new Timer(1000);
    loadingTimer.Elapsed += new ElapsedEventHandler(IncreaseLoadingPercentage);
    loadingTimer.Start();
}

private void IncreaseLoadingPercentage(object source, EventArgs e)
{
    loadedPercents += getLoadingPercentsPerSecond();
    loadingProgressChanged(loadedPercents);
}

Form sources: In constructor

router.loadingProgressChanged += new AbstractRouter.LoadingProgressChanged(percentageChanged);

Body of percentageChanged

public void percentageChanged(int percs)
{
    progressBar1.Value = percs;
}

And I get error

An exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll but was not handled in user code

Additional information: Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on.

If there is a handler for this exception, the program may be safely continued.

I understand why it happens: it seems that percentageChanged form is called in timer thread. But how to implement it correctly? Thanks!

slugster
  • 49,403
  • 14
  • 95
  • 145
  • 1
    Check out this tutorial on [dotnetperls](http://www.dotnetperls.com/progressbar). It shows how to update a `ProgressBar` control from a `BackgroundWorker` and the example even uses `Thread.Sleep` to update it every nth of a second. Sounds pretty damn close to what you're trying to do, while also probably being a little closer to a real world example of updating and using a progress bar and background workers. – sab669 Dec 15 '15 at 20:31
  • search in the upper right hand corner. Search for "accessed from a thread other than the thread it was created on" – Sorceri Dec 15 '15 at 20:32
  • You should probably just use the WinForms.Timer instead. – LarsTech Dec 15 '15 at 20:37

1 Answers1

1

Try with something like this:

public void percentageChanged(int percs)
{
   Invoke(new Action(() =>
   {
     progressBar1.Value = percs;
   }));
}
Ricardo Polo Jaramillo
  • 12,110
  • 13
  • 58
  • 83