Click here to Skip to main content
15,881,204 members
Articles / General Programming / Threads
Tip/Trick

Background Worker Queue in C#

Rate me:
Please Sign up or sign in to vote.
4.74/5 (12 votes)
27 Aug 2015CPOL1 min read 30.1K   36   7
How to implement the Queue of Background Worker

Introduction

I need to create the Queue of Backgroundworker so i can add actions to it and Run action when first one is completed till the Queue has something to run.

Background

I found it usefull for TreeView item selection where on selection we need to execute some action but sequentially without freezing the UI.

Using the code

CustomWorker class is a wrapper class of Backgroundworker which has sender property, sender property can be set as any sender where operation is being performed, in my case sender was TreeView checkbox selected item.

"QueueWorker" function accepts the queue object, sender and all required actions to be performed for each worker, in this example i have taken DoWork, WorkerCompleted, ProgressChanged and one custom action which i invoke to display errors if any when worker queue is empty.

C#
public class CustomWorker : BackgroundWorker
    {
        public CustomWorker(object sender)
        {
            this.Sender = sender;
        }

        public object Sender { get; private set; }

        public static void QueueWorker(
                            Queue<CustomWorker> queue,
                            object item,
                            Action<object, DoWorkEventArgs> action,
                            Action<object, RunWorkerCompletedEventArgs> actionComplete,
                            Action<RunWorkerCompletedEventArgs> displayError,
                            Action<object, ProgressChangedEventArgs> progressChange)
        {
            if (queue == null)
                throw new ArgumentNullException("queue");

            using (var worker = new CustomWorker(item))
            {
                worker.WorkerReportsProgress = true;
                worker.WorkerSupportsCancellation = true;

                worker.ProgressChanged += (sender, args) =>
                {
                    progressChange.Invoke(sender, args);
                };

                worker.DoWork += (sender, args) =>
                {
                    action.Invoke(sender, args);
                };

                worker.RunWorkerCompleted += (sender, args) =>
                {
                    actionComplete.Invoke(sender, args);
                    queue.Dequeue();
                    if (queue.Count > 0)
                    {
                        var next = queue.Peek();
                        next.ReportProgress(0, "Performing operation...");
                        next.RunWorkerAsync(next.Sender);
                    }
                    else
                        displayError.Invoke(args);
                };

                queue.Enqueue(worker);
                if (queue.Count == 1)
                {
                    var next = queue.Peek();
                    next.ReportProgress(0, "Performing operation...");
                    next.RunWorkerAsync(next.Sender);
                }
            }
        }
    }

Usage of CustomWorker is as below, a empty object of Queue, sender and actions are passed.

QueueWorker function will update the queue by creating the background worker for each action and queue them for execution.

C#
var workerQueue = new Queue<CustomWorker>();
private void SelectTreeViewCheckBox(object sender)
        {
            CustomWorker.QueueWorker(
                this.workerQueue,
                sender,
                (x, e) =>
                {
                    //// some custom do work logic.
                },
                (x, e) =>
                {
                    //// some custom completed logic.
                },
                (e) =>
                {
                    //// some custom display error logic.
                },
                (x, e) =>
                {
                    //// Progress change logic.
                    this.ProgressValue = e.ProgressPercentage;
                    this.Status = e.UserState.ToString();
                });
        }

Points of Interest

I was using the Backgroundworker for performing some operation on each checkbox selection of treeview and all selection have some dependency, so i have to use some locking to avoid updating objects by different workers at same time, once i implemented this Queue of Workers i didn't require lock and handling of selection became seamless.

History

1.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) ABB
India India
Working in Software Development since 2007.
Work in .Net/VC++/COM.
work in Process Automation domain.

Comments and Discussions

 
Generalmy vote of 1 Pin
Mr.PoorEnglish6-Sep-15 3:17
Mr.PoorEnglish6-Sep-15 3:17 
GeneralRe: my vote of 1 Pin
Chandra Shekhar Joshi15-Sep-15 19:45
Chandra Shekhar Joshi15-Sep-15 19:45 
GeneralRe: my vote of 1 Pin
Mr.PoorEnglish15-Sep-15 20:53
Mr.PoorEnglish15-Sep-15 20:53 
QuestionNice Article Pin
Santhakumar Munuswamy @ Chennai29-Aug-15 19:35
professionalSanthakumar Munuswamy @ Chennai29-Aug-15 19:35 
GeneralMy vote of 5 Pin
JayantaChatterjee28-Aug-15 2:07
professionalJayantaChatterjee28-Aug-15 2:07 
QuestionSample project would have be nice Pin
fredatcodeproject28-Aug-15 1:29
professionalfredatcodeproject28-Aug-15 1:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.