none
Run BackgroundWorker Processes Sequentially RRS feed

  • Question

  • The Situation: I have seen one thread that asks a similar question but is more convoluted than what I am trying to accomplish. I am migrating from MATLAB to C# so I am a novice with event handlers. I am able to run one BackgroundWorker process at a time with each having its own button and progress bar.

    The Problem: I would like to run three BackgroundWorker processes by using one button (i.e. by performing one click) and having the tasks completed in sequence i.e. backgroundWorker1 (and its progress bar and "stage 1 complete" label) followed by backgroundWorker2 (and its progress bar and "stage 2 complete" label) followed by backgroundWorker3 (and its progress bar  and "stage 3 complete" label). Thank you.

    The Code: Below is the whole code that I currently have but it only executes backgroundWorker1 (and its progress bar and "stage 1 complete" label) since I do not know how to incorporate backgroundWorker2 and backgroundWorker3. Form1.cs has 1 Button, 3 ProgressBar, 3 Label, and 3 BackgroundWorker components.

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Threading;

    namespace BackGroundWorkerExample
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            private int progBar1Max = 25;
            private int progBar2Max = 10;
            private int progBar3Max = 50;

            private void button1_Click(object sender, EventArgs e)
            {
                // start backgroundWorker1
                backgroundWorker1.RunWorkerAsync();
                // disable button after click
                button1.Enabled = false;
            }

            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                for (int progBar1Val = 1; progBar1Val <= progBar1Max; progBar1Val++)
                {
                    // wait 100 milliseconds
                    Thread.Sleep(100);
                    // report progress
                    backgroundWorker1.ReportProgress(progBar1Val);
                }
            }

            private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                // change the value of progressBar1 to the backgroundWorker1 progress
                progressBar1.Value = e.ProgressPercentage;
                progressBar1.Maximum = progBar1Max;
            }

            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                label1.Text = "stage 1 complete";
            }

            private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
            {
                for (int progBar2Val = 1; progBar2Val <= progBar2Max; progBar2Val++)
                {
                    // wait 250 milliseconds
                    Thread.Sleep(250);
                    // report progress
                    backgroundWorker2.ReportProgress(progBar2Val);
                }
            }

            private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                // change the value of the ProgressBar to the BackgroundWorker progress
                progressBar2.Value = e.ProgressPercentage;
                progressBar2.Maximum = progBar2Max;
                // set the text
                this.Text = e.ProgressPercentage.ToString();
            }

            private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                label2.Text = "stage 2 complete";
            }

            private void backgroundWorker3_DoWork(object sender, DoWorkEventArgs e)
            {
                for (int progBar3Val = 1; progBar3Val <= progBar3Max; progBar3Val++)
                {
                    // wait 50 milliseconds
                    Thread.Sleep(50);
                    // report progress
                    backgroundWorker3.ReportProgress(progBar3Val);
                }
            }

            private void backgroundWorker3_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                // change the value of the ProgressBar to the BackgroundWorker progress
                progressBar3.Value = e.ProgressPercentage;
                progressBar3.Maximum = progBar3Max;
                // set the text
                this.Text = e.ProgressPercentage.ToString();
            }

            private void backgroundWorker3_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                label3.Text = "stage 3 complete";
            }
        }
    }


    • Edited by tarajali Saturday, September 8, 2018 8:47 PM
    Saturday, September 8, 2018 8:32 PM

Answers

  • The dirty or quick solution is to use the Completed event of the background worker after which you want the other one to be started :

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        label1.Text = "stage 1 complete";
        backgroundWorker2.RunWorkerAsync();
    }

    and same way in the backgroundWorker2 completed event you can start the third one:

    private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        label2.Text = "stage 2 complete";
        backgroundWorker2.RunWorkerAsync();
    }

    and a better approach to this kind of scenario is using Tasks for which you can take a look at following two posts:

    Running a collection of BackgroundWorkers one after the other

    https://blogs.msdn.microsoft.com/csharpfaq/2010/06/01/parallel-programming-in-net-framework-4-getting-started/

    Hope it helps!


    [If a post helps to resolve your issue, please click the "Mark as Answer" of that post or click Answered"Vote as helpful" button of that post. By marking a post as Answered or Helpful, you help others find the answer faster. ]


    Blog | LinkedIn | Stack Overflow | Facebook
    profile for Ehsan Sajjad on Stack Exchange, a network of free, community-driven Q&A sites



    • Edited by Ehsan Sajjad Saturday, September 8, 2018 8:47 PM
    • Marked as answer by tarajali Saturday, September 8, 2018 8:49 PM
    Saturday, September 8, 2018 8:45 PM

All replies

  • The dirty or quick solution is to use the Completed event of the background worker after which you want the other one to be started :

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        label1.Text = "stage 1 complete";
        backgroundWorker2.RunWorkerAsync();
    }

    and same way in the backgroundWorker2 completed event you can start the third one:

    private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        label2.Text = "stage 2 complete";
        backgroundWorker2.RunWorkerAsync();
    }

    and a better approach to this kind of scenario is using Tasks for which you can take a look at following two posts:

    Running a collection of BackgroundWorkers one after the other

    https://blogs.msdn.microsoft.com/csharpfaq/2010/06/01/parallel-programming-in-net-framework-4-getting-started/

    Hope it helps!


    [If a post helps to resolve your issue, please click the "Mark as Answer" of that post or click Answered"Vote as helpful" button of that post. By marking a post as Answered or Helpful, you help others find the answer faster. ]


    Blog | LinkedIn | Stack Overflow | Facebook
    profile for Ehsan Sajjad on Stack Exchange, a network of free, community-driven Q&A sites



    • Edited by Ehsan Sajjad Saturday, September 8, 2018 8:47 PM
    • Marked as answer by tarajali Saturday, September 8, 2018 8:49 PM
    Saturday, September 8, 2018 8:45 PM
  • Thank you very much, Ehsan! I will use the quick and dirty solution (which I have tested and works for now) and read the links you provided to see it I can follow and implement/test the more elegant approaches.
    Saturday, September 8, 2018 8:51 PM