BackgroundWorker DoWork function is not being called

598 Views Asked by At

I've created a loading form within my C# WinForms application that is shown during long processes. I've added a progress bar to my loading form that I would like to update to give some feedback of loading to the user.

Within my loading form code, I have created a new BackgroundWorker and added DoWork and ProgressChanged event handlers. The problem is that the backgroundWorker_ProgressChanged is not being called. I have inserted break points into the function and they are not caught.

Where am I going wrong? Any help appreciated. Thanks.

frmLoading:

public frmLoading()
        {
            InitializeComponent();

            //check if bg worker is null
            if (backgroundWorker == null)
            {
                backgroundWorker = new BackgroundWorker();

                backgroundWorker.DoWork += backgroundWorker_DoWork;
                backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;

                
            }

            backgroundWorker.WorkerReportsProgress = true;

            //start
            backgroundWorker.RunWorkerAsync();
        }

backgroundWorker_DoWork:

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

backgroundWorker_ProgressChanged:

private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //update value of progress bar
            progressBar1.Value = e.ProgressPercentage;
            //set the text of the progress bar
            this.Text = e.ProgressPercentage.ToString();
        }
1

There are 1 best solutions below

0
Enigmativity On BEST ANSWER

Here's how you would do this with Progress<int> and Task.Run:

public frmLoading()
{
    InitializeComponent();

    IProgress<int> progress = new Progress<int>(p =>
    {
        //update value of progress bar
        progressBar1.Value = p;
        //set the text of the progress bar
        this.Text = p.ToString();
    });

    Task.Run(async () =>
    {
        for (int i = 1; i <= 100; i++)
        {
            await Task.Delay(TimeSpan.FromSeconds(0.1));
            progress.Report(i);
        }
    });
}

Personally I prefer Microsoft's Reactive Framework:

public frmLoading()
{
    InitializeComponent();

    Observable
        .Interval(TimeSpan.FromSeconds(0.1))
        .Take(100)
        .ObserveOn(this)
        .Select(p => p + 1)
        .Subscribe(p =>
        {
            //update value of progress bar
            progressBar1.Value = p;
            //set the text of the progress bar
            this.Text = p.ToString();
        });
}