Search code examples
c#winformsprogress-barbackgroundworker

Using BackgroundWorker with Progressbar in WindowsForm with different Classes


I have 2 different classes downloadWiki and GetLinks, each one has a loop that needs a bit time to execute, and a Form.cs class where my buttons and progress bar are.

My downloadWiki has a loop that loops through different html pages, and the GetLinks class has a loop that gets every link on each Wiki page and sends it to my downloadWiki class. After some if statements I download some of those wikis. Now my problem, I tried the last 2 hours to implement a progress bar and backgroundworker for the loop with the links and for the one which downloads the wikipages. But I didn't found a solution. This is the code I execute in my Windows Forms code. So I don't know how to send a backgroundWorker to those two classes.

Please comment if you need more Code.

Sorry if this is easy to google question, but I'm a "newbie" in C#

    private void button1_Click(object sender, EventArgs e)
    {
        DownloadWikis wikis = new DownloadWikis();
    }

Solution

  • First, you need to configure your backgroundworker:

        public FrmMain()
        {
            InitializeComponent();
    
            _backgroundWorker.WorkerReportsProgress = true;
            _backgroundWorker.ProgressChanged += _backgroundWorker_ProgressChanged;
            _backgroundWorker.DoWork += _backgroundWorker_DoWork;
            _backgroundWorker.RunWorkerCompleted += _backgroundWorker_RunWorkerCompleted;
        }
    

    You want a progressBar, so your backgroundWorker needs to report progress. The work will be done asynchronously, so you need to specify a delegate where your download will be executed.

        private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            DownloadWikis wikis = new DownloadWikis();
    
        }
    

    In your DownloadWikis class, write a delegate. It will help us to call the backgroundworker ReportProgress method.

         public delegate void ReportProgressDelegate(int percentage);
    

    Update your Download signature, it should be like this:

        public void Download(ReportProgressDelegate reportProgress)
        {
            // FirstLoop
            for(int i=0; i < 100; i++)
            {
                // Do some work with GetLinks
                // this will call the backgroundworker ReportProgress method.
                reportProgress(i);
            }
        }
    

    Now, you can complete with this:

        private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            DownloadWikis wiki = new DownloadWikis();
            wiki.Download(_backgroundWorker.ReportProgress);
        }
    

    To handle the progress bar value, the second delegate is here:

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

    With this step, you will be able to see when your work will be completed:

         private void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("It's done !");
        }
    

    Last step, the easy one:

        private void btnDownloadWikis_Click(object sender, EventArgs e)
        {
            _backgroundWorker.RunWorkerAsync();
        }
    

    Now, you have to do some maths do determine your percentage.