Programmer
Programmer

Reputation: 381

progress bar in background worker get argument which being updated in the main thread c# wpf

I have the main thread which is wizard in WPF.

after user finished set the properties of the wizard, it processing data.

It takes a few seconds and I would like to raise a progress bar which report on the progress.

Hence, I set always on the main thread variable call currentStep.

I have totally thresholdStep steps which equals to 12.

So I want that the progress bar will work as a thread but it will also will be connected to the main thread by using currentStep variable.

So, I used by background worker like this:

public partial class MessageWithProgressBar : Window
{
    private BackgroundWorker backgroundWorker = new BackgroundWorker();
    public MessageWithProgressBar()
    {
        InitializeComponent();
        backgroundWorker.WorkerReportsProgress = true;
        backgroundWorker.ProgressChanged += ProgressChanged;
        backgroundWorker.DoWork += DoWork;
        backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
    }

    private void DoWork(object sender, DoWorkEventArgs e)
    {
        Thread.Sleep(100);
        int i = (int)e.Argument;
        backgroundWorker.ReportProgress((int)Math.Floor((decimal)(8*i)));
        if (i > GeneralProperties.General.thresholdStep)
            backgroundWorker.ReportProgress(100);
    }

    private void ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progress.Value = e.ProgressPercentage;
    }

    private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        WindowMsg msg = new WindowMsg();
        msg.Show();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        if (backgroundWorker.IsBusy == false)
            backgroundWorker.RunWorkerAsync(GeneralProperties.General.currentStep);
    }
}

In addition, I called the background worker from the main thread as below:

MessageWithProgressBar progress = new MessageWithProgressBar();
progress.Show();

What acutally happens is that DoWork called only once with currentStep = 1 and it don't updates in relation to the main thread which also updated currentStep dependents on it's progress.

Any ideas how to solve it?

Thanks!

Upvotes: 0

Views: 668

Answers (1)

Kylo Ren
Kylo Ren

Reputation: 8803

Change your DoWork method like below:

 private void DoWork(object sender, DoWorkEventArgs e)
    {
        Thread.Sleep(100);
        int i = (int)e.Argument;
        do
        {   
            i = GeneralProperties.General.currentStep;
            backgroundWorker.ReportProgress((int)Math.Floor((decimal)(8 * i)));
            if (i > GeneralProperties.General.thresholdStep)
               backgroundWorker.ReportProgress(100);
        }
        while (i < GeneralProperties.General.thresholdStep);
    }

Just make sure your are not getting thread synchronization problem with GeneralProperties.General object, if you are then use lock when accessing the object.

UPDATE:

For update problem:

 private void ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
        {
            progress.Value = e.ProgressPercentage;
        }), null);
    }

Upvotes: 2

Related Questions