-1

The most examples are with a for loop, and they work, and explain how a BackgroundWorker works. But how do I use a ProgressBar for a method that converts data? It takes a few minutes and I want to show the user the progress of the method.

private void DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i <= 100; i++)
    {             
        Thread.Sleep(100);
        backgroundWorker.ReportProgress(i);
    }
}

Here you give always I to update the value. But what if I want to do this?

private void DoWork(object sender, DoWorkEventArgs e)
{
    ConvertDataMethod();

    backgroundWorker.ReportProgress(i); <- What do I do here??
}

private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
}
Claire Nielsen
  • 1,881
  • 1
  • 14
  • 31
user7998549
  • 131
  • 3
  • 15
  • you need to handle the event ProgressChanged. – Florian Jan 15 '18 at 13:32
  • @Florian added the ProgressChanged – user7998549 Jan 15 '18 at 13:36
  • You say you're converting data, but how are u doing it ? There are several ways you could do it, using progressBar.Maximum attribute and ProgressPercentage attribute of object event (of type ProgressEventChanged). Maybe if you give more informations about your converting data method, we could help – Florian Jan 15 '18 at 13:49
  • @Florian my bad. My converting method actually reads out an Excel file, reforms the data and writes it back to another Excel file. – user7998549 Jan 15 '18 at 13:52
  • 1) Could you show a piece of code ? 2) If you only want to show user that something is running background, what about ProgressBar.Style = MarqueeStyle ? – Florian Jan 15 '18 at 13:59
  • @Florian yes option 2, in WPF it is IsIndeterminate. – user7998549 Jan 15 '18 at 14:22
  • I checked MarqueeStyle WPF for you, I suggest you to check this post if you can't report the process time proeprly :-) https://stackoverflow.com/questions/638650/how-do-i-make-a-marquee-progress-bar-in-wpf – Florian Jan 15 '18 at 14:25
  • Yes I know how to set that property, but when I click start converting button the ProcessBar also freezes :D, new to threading.. – user7998549 Jan 15 '18 at 14:45
  • I'm afraid I can't help you much on WPF stuff. Maybe this easy-to-understand tuto will help you :) http://www.wpf-tutorial.com/misc-controls/the-progressbar-control/ – Florian Jan 15 '18 at 14:52
  • Oh well thanks anyway :) I let it rest getting this 'The calling thread cannot access this object because a different thread owns it' – user7998549 Jan 15 '18 at 15:01
  • If you search on google I'm sure you'll have some informations. Using thread, you must use method Invoke() when running on another thread :-) – Florian Jan 15 '18 at 15:04
  • Ye I will ;). But I followed a few samples. – user7998549 Jan 15 '18 at 15:12

2 Answers2

0

You can report progress only if you have some way to determine your current progress. When you can't know for how long will your operation take, you have to resort to other methods of progress indication. There are many ways to indicate that your application is performing a lengthy operation without displaying an actual progress.

Spinner is one common example of this: you instantiate your spinner, make is to start spinning and run your background worker. Once the backgroundworker's work completed, you hide the spinner or stop it.

This way you don't use ReportProgress at all (since you don't have any means to report progress from your lengthy conversion operation), you only indicate that your application is busy doing the conversion.

...
StartSpinner();
worker.DoWork += (sender,eargs) => ConvertDataMethod();
worker.RunWorkerCompleted += (sender,eargs) => StopSpinner();
worker.RunWorkerAsync();
...
rs232
  • 1,248
  • 8
  • 16
0

I think events will be more suitable for your purpose.

1)Declare your EventHandler

public event EventHandler ProgressChanged;

2)Then make raising event method like this

protected virtual void OnProgressChanged(CustomEventArgs e)
{
  if (ProgressChanged != null)
  {
    ProgressChanged(this, new CustomEventArgs() { MyValue = e.MyValue });
  }
}

3)As you can see, I declared custom class for EventArgs, code below. Do not forget to inherit from EventArgs class.

  class CustomEventArgs : EventArgs
  {
    public int MyValue { get; set; }
  }

4)You must subscribe to your event

ProgressChanged += Program_ProgressChanged;

private void Program_ProgressChanged(object sender, EventArgs e)
{
  //Your progressBar update here
}

5)Finally you can raise your event with this code snippet

OnProgressChanged(new CustomEventArgs()
{
  MyValue = 0 //progressBar Value
});

If using background worker is necessary, please, just ignore my answer.

Thanks. :)