Search code examples
backgroundworker

Help with C#.NET BackgroundWorker


I'm trying a very simple test for using BackgroundWorker in my app. I can see that the background worker is doing it's thing but for some reason the main thread is getting any progress notifications.

I must be missing something very basic here. Can anybody point out where I'm going wrong?

Here's the code for my simple test:

namespace TestBackgroundWorker
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            progressBar1.Maximum = 100;
            progressBar1.Minimum = 0;
            progressBar1.Value = 0;
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.RunWorkerAsync();
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            int progress = 0;
            while (true)
            {
                Thread.Sleep(1000);
                System.Diagnostics.Debug.WriteLine("worker: progress={0}", progress);
                worker.ReportProgress(progress);
                progress = (progress + 10) % 100;
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("main: process progress={0}", e.ProgressPercentage);
            progressBar1.Value = e.ProgressPercentage;
        }
    }
}

And then here is what I get on the output window. It shows that the worker is waking up and doing its thing but the main thread isn't getting any progress updates:

worker: progress=0
worker: progress=10
worker: progress=20
worker: progress=30
worker: progress=40
worker: progress=50
worker: progress=60
worker: progress=70
worker: progress=80
worker: progress=90
worker: progress=0
worker: progress=10
worker: progress=20
worker: progress=30
worker: progress=40
worker: progress=50
worker: progress=60
worker: progress=70
worker: progress=80
The thread '<No Name>' (0x1e84) has exited with code 0 (0x0).
worker: progress=90
worker: progress=0
worker: progress=10
worker: progress=20
worker: progress=30
worker: progress=40
worker: progress=50
worker: progress=60
worker: progress=70
worker: progress=80
worker: progress=90
worker: progress=0
worker: progress=10
worker: progress=20
worker: progress=30
worker: progress=40
worker: progress=50
worker: progress=60
worker: progress=70
worker: progress=80
worker: progress=90
worker: progress=0
worker: progress=10
worker: progress=20
worker: progress=30
worker: progress=40
worker: progress=50
The thread 'vshost.RunParkingWindow' (0x2760) has exited with code 0 (0x0).
The thread '<No Name>' (0x29c8) has exited with code 0 (0x0).
The program '[3528] TestBackgroundWorker.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).

Solution

  • This may sound like a stupid question but are you sure the callback function is bound to the ProgressChanged event ?

    The following code:

    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Threading;
    
    namespace ConsoleApplication2
    {
        class Program
        {
            [STAThread]
            static void Main(string[] args)
            {
                new Program().Run();
            }
    
            void Run()
            {
                var worker = new BackgroundWorker { WorkerReportsProgress = true };
    
                worker.ProgressChanged += WorkerOnProgressChanged;
                worker.DoWork += WorkerOnDoWork;
                worker.RunWorkerAsync();
    
                Console.ReadKey();
            }
    
            private void WorkerOnDoWork(object sender, DoWorkEventArgs e)
            {
                for (int i = 0; ; i++)
                {
                    Debug.WriteLine("[Thread #{0,2} (worker)] Progress:{1}", Thread.CurrentThread.ManagedThreadId, i);
                    (sender as BackgroundWorker).ReportProgress(i);
                    Thread.Sleep(1000);
                }
            }
    
            private void WorkerOnProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                Debug.WriteLine("[Thread #{0,2} (main  )] Progress:{1}", Thread.CurrentThread.ManagedThreadId, e.ProgressPercentage);
            }
        }
    }
    

    will output the following:

    [Thread # 7 (worker)] Progress:0
    [Thread #11 (main  )] Progress:0
    [Thread # 7 (worker)] Progress:1
    [Thread #11 (main  )] Progress:1
    [Thread # 7 (worker)] Progress:2
    [Thread #11 (main  )] Progress:2
    [Thread # 7 (worker)] Progress:3
    [Thread #11 (main  )] Progress:3
    [Thread # 7 (worker)] Progress:4
    [Thread #11 (main  )] Progress:4
    [Thread # 7 (worker)] Progress:5
    [Thread #11 (main  )] Progress:5
    [Thread # 7 (worker)] Progress:6
    [Thread #11 (main  )] Progress:6
    [Thread # 7 (worker)] Progress:7
    [Thread #11 (main  )] Progress:7
    [Thread # 7 (worker)] Progress:8
    [Thread #12 (main  )] Progress:8