Jitesh Byahut 7/26/2014 2135

BackgroundWorker in Windows Application

If your application containing long runing task, then your application might become unresponsive and may be hung up. The reason behind it is that your long runing task is placed on the thread that responsible for updating the UI. So to improve the performance of application in this senario, you can place your long runing task into another thread.

BackgroundWorker Class provide facility to long runing task into another thread that responsible to update the UI.

1. Create a BackgroundWorker instance.

2. Create a method worker_DoWork that follow the DoWorkEventHandler signature.

3. Call long runing task in the worker_DoWork. When task is completed assign the result of the operation to the Result property of the DoWorkEventArgs parameter.

4. Call the RunWorkerAsync method to start the background work on Button click or any other way.

5. When you call RunWorkerAsync method then need to confirm that BackgroundWorker is not busy by using IsBusy property.

public partial class BackgrounWorker : Form

    {

        private BackgroundWorker bgwork;

 

        public BackgrounWorker()

        {

            InitializeComponent();

 

            bgwork = new BackgroundWorker();            

            bgwork.DoWork += new DoWorkEventHandler(worker_DoWork);

        }

 

        // Trigger LongRunningWork

        void worker_DoWork(object sender, DoWorkEventArgs e)

        {

           LongRunningWork();

        }

       

        // Long running task

        private double LongRunningWork()

        {

            double total = 1;

 

            for (int i = 1; i <= 100; i++)

            {                

                total = total * i;

                System.Threading.Thread.Sleep(100);                

            } 

            return total;

        }

 

        // Start DoWork

        private void btnStart_Click(object sender, EventArgs e)

        {

            if (!bgwork.IsBusy)

            {

                bgwork.RunWorkerAsync();

            }

        } 

    }

BackgroundWorker's RunWorkerCompleted Event

If your long running task returns any result then, store that results into the Result property of the DoWorkEventArgs parameter.

Create a method worker_complete that follows the RunWorkerCompletedEventHandler signature.

In this method, you can get the result of long runing task and update the UI.

bgwork.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_complete);

// Trigger LongRunningWork

void worker_DoWork(object sender, DoWorkEventArgs e)

{

       e.Result = LongRunningWork();

}



// Trigger when DoWork is completed

void worker_complete(object sender, RunWorkerCompletedEventArgs e)

{

     lblResult.Text = e.Result.ToString();

}

BackgroundWorker's ProgressChanged Event

Create a method worker_ProgessChanged that follows the ProgressChangedEventHandler signature.

Set BackgroundWorker's propery WorkerReportsProgress to true.

Now you can send the progress from long runing task to how much it has completed.

Retrieve progress report in worker_ProgessChanged method.

bgwork.WorkerReportsProgress = true;

bgwork.ProgressChanged += new ProgressChangedEventHandler(worker_ProgessChanged);

 

// Tracking progress

void worker_ProgessChanged(object sender, ProgressChangedEventArgs e)

{

      lblProgress.Text = e.ProgressPercentage + " %";

}

 

// Long running task

private double LongRunningWork()

{

    double total = 1;

 

    for (int i = 1; i <= 100; i++)

    {

                

        total = total * i;

        System.Threading.Thread.Sleep(100);

        bgwork.ReportProgress(i);                

    } 

   return total;

}

 

BackgroundWorker's WorkerSupportsCancellation Property

Set BackgroundWorker's property WorkerSupportsCancellation to true.

Now add a Button and on click just call CancelAsync method of BackgroundWorker.

Ok next is check CancellationPending propery every time in long runing task. Whenever you call CancelAsync then it will set the CancellationPending to true.

bgwork.WorkerSupportsCancellation = true;


private void btnCancel_Click(object sender, EventArgs e)

{

    bgwork.CancelAsync();

    lblProgress.Text = "Task Cancelled";

}

 

// Long running task

private double LongRunningWork()

{

     double total = 1;

 

     for (int i = 1; i <= 100; i++)

     {

         if (bgwork.CancellationPending)

          {

             break;

          }

          else

          {

             total = total * i;

             System.Threading.Thread.Sleep(100);

             bgwork.ReportProgress(i);

          }

    }

 

    return total;

}

 

Complete example of BackgroundWorker Class:

public partial class BackgrounWorker : Form

    {

        private BackgroundWorker bgwork;

 

        public BackgrounWorker()

        {

            InitializeComponent();

 

            bgwork = new BackgroundWorker();

            bgwork.WorkerSupportsCancellation = true;

            bgwork.WorkerReportsProgress = true;

            bgwork.DoWork += new DoWorkEventHandler(worker_DoWork);

            bgwork.ProgressChanged += new ProgressChangedEventHandler(worker_ProgessChanged);

            bgwork.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_complete);

        }

 

        // Start DoWork

        private void btnStart_Click(object sender, EventArgs e)

        {

            if (!bgwork.IsBusy)

            {

                bgwork.RunWorkerAsync();

            }

        }

 

        // Trigger LongRunningWork

        void worker_DoWork(object sender, DoWorkEventArgs e)

        {

            e.Result = LongRunningWork();

        }

 

        // Trigger when DoWork is completed

        void worker_complete(object sender, RunWorkerCompletedEventArgs e)

        {

            lblResult.Text = e.Result.ToString();

        }

 

        // Tracking progress

        void worker_ProgessChanged(object sender, ProgressChangedEventArgs e)

        {

            lblProgress.Text = e.ProgressPercentage + " %";

        }

       

        // Long running task

        private double LongRunningWork()

        {

            double total = 1;

 

            for (int i = 1; i <= 100; i++)

            {

                if (bgwork.CancellationPending)

                {

                    break;

                }

                else

                {

                    total = total * i;

                    System.Threading.Thread.Sleep(100);

                    bgwork.ReportProgress(i);

                }

            }

 

            return total;

        }

 

        private void btnCancel_Click(object sender, EventArgs e)

        {

            bgwork.CancelAsync();

            lblProgress.Text = "Task Cancelled";

        }      

    }

Demo:



Please give your feedback for improving this page