Share via


Thread vs Task vs BackgroundWorker

Question

Tuesday, May 12, 2015 3:25 PM

hello,

    i am a beginner at programming, i learn new stuff every day, for some time now i learned and used threads, tasks, and backgroundworkers, but i still don't know how to properly use them. when should i use a task or thread or backgroundworker.

   is there a correct way of using them?

thank you, hope my question is now so foolish.

All replies (6)

Tuesday, May 12, 2015 6:30 PM âś…Answered | 1 vote

for example.. now i need to implement a "thread" for a windows form that reads from a xml file and updates a database every 20 minutes. for this, now i use a simple thread, that runs in the background. is this the correct approach?

thank you all for your answers . i haven't knew until now about the 'await' and 'async'.

There is *usually* never a good reason to instantiate the Thread object directly and call it. I recommend using a BackgroundWorker for this instead. See this MSDN article on tips for implementing a BackgroundWorker: https://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx

Async/Await pattern is great for execute something that is resource bound (not CPU bound) like reading a file or writing to a database. This will release the thread back to the o/s while the external operation is being executed so the thread does not block. It is a very easy construct to use.

For comparisons on BackgroundWorker and the async/await pattern see this post (its the 2nd response so not the answer), the author does a very nice job at comparing the 2 approaches. http://stackoverflow.com/a/12415691/1260204

Mark as answer or vote as helpful if you find it useful | Igor


Tuesday, May 12, 2015 3:31 PM | 1 vote

A background worker is just a simple implementation of threading with Windows Forms. 

If you want to do assynchonous tasks (which treading is) then take currently the newer approach in C# with the keywords in the language Await and Async and the created classes therefore.

https://msdn.microsoft.com/en-us/library/hh456528.aspx?f=255&MSPPError=-2147217396

Success
Cor


Tuesday, May 12, 2015 4:41 PM | 1 vote

If you are new to multithreading and all you want to do is run stuff in the background (so the UI-Thread is not locked up), BackgroundWorkers are a very good place to start.
async+await are also easy to use. It takes even more of the plumbing work from you, letting the compiler do the heavy lifting. But I found it slighly harder to understand then the BGW for the beginner.

Background Threading is a reqired technique in the current age, so you should start with that.

If you want to do actuall multithreading (multiple threads solving part of the same problem in paralell), then you have go for tasks and threads.
This is a lot more tricky then simple background threading. You might want to wait before you try that.

As a side note never try to learn multithreading on a console. GUI's are just so much easier to learn this.


Tuesday, May 12, 2015 5:12 PM

for example.. now i need to implement a "thread" for a windows form that reads from a xml file and updates a database every 20 minutes. for this, now i use a simple thread, that runs in the background. is this the correct approach?

thank you all for your answers . i haven't knew until now about the 'await' and 'async'.


Tuesday, May 12, 2015 6:46 PM

thank you for your answers,

@IWolbers i will use a BackgroundWorker for what i need now.


Tuesday, May 12, 2015 7:38 PM

thank you for your answers,

@IWolbers i will use a BackgroundWorker for what i need now.

If you need progress notification (a bar) BGW is a very good place to start.

Here is an old example for finding all the primes in a range of numbers with progress notification:

        #region Primenumbers
        private void btnPrimStart_Click(object sender, EventArgs e)
        {
            if (!bgwPrim.IsBusy)
            {
                //Prepare ProgressBar and Textbox
                int temp = (int)nudPrim.Value;
                pgbPrim.Maximum = temp;
                tbPrim.Text = "";

                //Start processing
                bgwPrim.RunWorkerAsync(temp);
            }
        }

        private void btnPrimCancel_Click(object sender, EventArgs e)
        {
            if (bgwPrim.IsBusy)
            {
                bgwPrim.CancelAsync();
            }
        }

        private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
        {
            int highestToCheck = (int)e.Argument;
            //Get a reference to the BackgroundWorker running this code
            //for Progress Updates and Cancelation checking
            BackgroundWorker thisWorker = (BackgroundWorker)sender;

            //Create the list that stores the results and is returned by DoWork
            List<int> Primes = new List<int>();
            

            //Check all uneven numbers between 1 and whatever the user choose as upper limit
            for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
            {
                //Report progress
                thisWorker.ReportProgress(PrimeCandidate);
                bool isNoPrime = false;

                //Check if the Cancelation was requested during the last loop
                if (thisWorker.CancellationPending)
                {
                    //Tell the Backgroundworker you are canceling and exit the for-loop
                    e.Cancel = true;
                    break;
                }

                //Determin if this is a Prime Number
                for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
                {
                    if (PrimeCandidate % j == 0)
                        isNoPrime = true;
                }

                if (!isNoPrime)
                    Primes.Add(PrimeCandidate);
            }

            //Tell the progress bar you are finished
            thisWorker.ReportProgress(highestToCheck);

            //Save Return Value
            e.Result = Primes.ToArray();
        }

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

        private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            pgbPrim.Value = pgbPrim.Maximum;
            this.Refresh();

            if (!e.Cancelled && e.Error == null)
            {
                //Show the Result
                int[] Primes = (int[])e.Result;

                StringBuilder sbOutput = new StringBuilder();

                foreach (int Prim in Primes)
                {
                    sbOutput.Append(Prim.ToString() + Environment.NewLine);
                }

                tbPrim.Text = sbOutput.ToString();
            }
            else 
            {
                tbPrim.Text = "Operation canceled by user or Exception";
            }
        }
        #endregion