11

I have a simple app which fires of a series of data intensive tasks. I'm not very experienced with WinForms and I was wondering the best way to do this without locking the interface. Can backgroundWorker be re-used, or is there another way to do this?

Thanks

Brian
  • 747
  • 3
  • 13
  • 22
  • I would use the backgroundworker. – Tomtom Jul 16 '12 at 08:28
  • If you only need one other thread I would use a background worker, they are very easy to use and most of the hard work has been done, providing you with straight forward events for different stages of the work completion. – Lloyd Powell Jul 16 '12 at 08:28
  • Use Backgroundworker if you need that thread to interact with the UI elements after finishing its intensive work. Other wise if you just want some other job for example filling up some container data from some where else which is used by Main UI at some other time or an event, then use normal thread. – Zenwalker Jul 16 '12 at 08:34
  • Well they user can fire off various different tasks which then perform database operations through the entityFramework. So, when the user has finished task A, can the backgroundworker be used again for task B? – Brian Jul 16 '12 at 08:36
  • http://www.dotnetperls.com/backgroundworker – adt Jul 16 '12 at 08:40
  • My concern is with adding my "long running task logic" to the DoWork event. I have a number of tasks that need to run and it doesn't seem practical to add them all to the one DoWork event. – Brian Jul 16 '12 at 11:13

4 Answers4

9

BackgroundWorker is a thread that also includes notification synchronization. For example, if you wanted to update your UI when the scan completes, a regular Thread cannot access the UI objects (only the UI thread can do that); so, BackgroundWorker provides a Completed event handler that runs on the UI thread when the operation completes.

for more info see: Walkthrough: Multithreading with the BackgroundWorker Component (MSDN)

and a simple sample code:

var worker = new System.ComponentModel.BackgroundWorker();
worker.DoWork += (sender,e) => Thread.Sleep(60000);
worker.RunWorkerCompleted += (sender,e) => MessageBox.Show("Hello there!");
worker.RunWorkerAsync();
Ria
  • 10,237
  • 3
  • 33
  • 60
7

backgroundWorker can be used.

its benefit - it allows you to update a progress bar and interact with UI controls. (WorkerReportsProgress)

Also it has a cancellation mechanism. (WorkerSupportsCancellation)

enter image description here

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
5

You can use BackgroundWorker for such requirements. Below is a sample which updates a label status based on percentage task [long running] completion. Also, there is a sample business class which sets some value and the value is set back to UI via ProgressChanged handler. DoWork is the place where you write your long running task logic. Copy-Paste the code below after adding a label and backgroundworker component on a Winforms app & give it a shot. You may debug across various handler [RunWorkerCompleted, ProgressChanged, DoWork] and have a look at InitWorker method. Notice the cancellation feature too.

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

namespace WindowsFormsApplication1
{
    public partial class Form3 : Form
    {
        private BackgroundWorker _worker;
        BusinessClass _biz = new BusinessClass();
        public Form3()
        {
            InitializeComponent();
            InitWorker();
        }

        private void InitWorker()
        {
            if (_worker != null)
            {
                _worker.Dispose();
            }

            _worker = new BackgroundWorker
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true
            };
            _worker.DoWork += DoWork;
            _worker.RunWorkerCompleted += RunWorkerCompleted;
            _worker.ProgressChanged += ProgressChanged;
            _worker.RunWorkerAsync();
        }


        void DoWork(object sender, DoWorkEventArgs e)
        {
            int highestPercentageReached = 0;
            if (_worker.CancellationPending)
            {
                e.Cancel = true;
            }
            else
            {
                double i = 0.0d;
                int junk = 0;
                for (i = 0; i <= 199990000; i++)
                {
                    int result = _biz.MyFunction(junk);
                    junk++;

                    // Report progress as a percentage of the total task.
                    var percentComplete = (int)(i / 199990000 * 100);
                    if (percentComplete > highestPercentageReached)
                    {
                        highestPercentageReached = percentComplete;
                        // note I can pass the business class result also and display the same in the LABEL  
                        _worker.ReportProgress(percentComplete, result);
                        _worker.CancelAsync();
                    }
                }

            }
        }

        void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                // Display some message to the user that task has been
                // cancelled
            }
            else if (e.Error != null)
            {
                // Do something with the error
            }
        }

        void ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            label1.Text =  string.Format("Result {0}: Percent {1}",e.UserState, e.ProgressPercentage);
        }
    }

    public class BusinessClass
    {
        public int MyFunction(int input)
        {
            return input+10;
        }
    }
}
Angshuman Agarwal
  • 4,796
  • 7
  • 41
  • 89
  • Thanks for the detailed response. My concern is with adding my "long running task logic" to the DoWork event. I have a number of tasks that need to run and it doesn't seem practical to add them all to the one DoWork event. – Brian Jul 16 '12 at 10:01
4

The background worker would be a good choice to start with

For more info look here http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

JohnnBlade
  • 4,261
  • 1
  • 21
  • 22