Running a collection of BackgroundWorkers one after the other
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
4
down vote
favorite
In my project, I had three BackgroundWorker
s that can be run independently, but I also wanted to allow the user to "Run All" of them, but not at the same time. They need to be run one after the other. So, I devised this class
to create a Queue
of BackgroundWorker
s, subscribe to their RunWorkerCompleted
event handler, and run the next worker in the Queue
.
I would like to know:
- If this is even a good idea
- If there are any potential bugs I might have overlooked
- If I've violated any normal .Net conventions.
- Any ways to improve the functionality, speed, or readability of the code
/// <summary>
/// Simplifies running a Queue of BackgroundWorkers one after the other without blocking the current thread.
/// </summary>
public class BackgroundWorkerQueue
/// <summary>Continue running BackgroundWorkerQueue if any BackgroundWorker causes an Exception.</summary>
public bool ContinueOnError get; set;
private Queue<QueuedWorker> Queue get; set;
public BackgroundWorkerQueue( )
this.Queue = new Queue<QueuedWorker>();
public static BackgroundWorkerQueue operator +( BackgroundWorkerQueue left, BackgroundWorker worker )
left.Add(worker);
return left;
public static BackgroundWorkerQueue operator +( BackgroundWorkerQueue left, QueuedWorker worker )
left.Add(worker);
return left;
/// <summary>Add a BackgroundWorker to the Queue</summary>
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
/// <param name="argument">A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</param>
public void Add( BackgroundWorker worker, object argument )
this.Queue.Enqueue(new QueuedWorker(worker,argument));
/// <summary>Add a BackgroundWorker to the Queue</summary>
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
public void Add( BackgroundWorker worker )
this.Queue.Enqueue(new QueuedWorker(worker,null));
/// <summary>Add a BackgroundWorker to the Queue</summary>
public void Add( QueuedWorker worker )
this.Queue.Enqueue(worker);
/// <summary>Starts execution of the BackgroundWorkers.</summary>
public void Run( )
Debug.Print("BackgroundWorkerQueue.Run(), 0 items in queue.", this.Queue.Count);
QueuedWorker q = this.Queue.Dequeue();
q.Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.Completed);
q.Worker.RunWorkerAsync(q.Argument);
private void Completed( object sender, RunWorkerCompletedEventArgs e )
Debug.Print("BackgroundWorkerQueue.Completed()");
BackgroundWorker worker = sender as BackgroundWorker;
if( worker != null )
/// <summary>Object containing a BackgroundWorker and optional Argument to be run.</summary>
public class QueuedWorker
/// <summary></summary>A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</summary>
public object Argument get; set;
/// <summary>BackgroundWorker to be run.</summary>
public BackgroundWorker Worker get; set;
public QueuedWorker()
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
/// <param name="argument">A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</param>
public QueuedWorker( BackgroundWorker worker, object argument )
this.Worker = worker;
this.Argument = argument;
Example Usage:
var q = new BackgroundWorkerQueue();
q.Add(InventoryBgWorker,"FIN STOCK"); // to add a worker, you can call one of the Add(...) methods
q += PartDataBgWorker; // or you can use the += operator
q += OpenOrdersBgWorker;
q.Run(); // Does not block current thread.
c# multithreading .net queue
add a comment |Â
up vote
4
down vote
favorite
In my project, I had three BackgroundWorker
s that can be run independently, but I also wanted to allow the user to "Run All" of them, but not at the same time. They need to be run one after the other. So, I devised this class
to create a Queue
of BackgroundWorker
s, subscribe to their RunWorkerCompleted
event handler, and run the next worker in the Queue
.
I would like to know:
- If this is even a good idea
- If there are any potential bugs I might have overlooked
- If I've violated any normal .Net conventions.
- Any ways to improve the functionality, speed, or readability of the code
/// <summary>
/// Simplifies running a Queue of BackgroundWorkers one after the other without blocking the current thread.
/// </summary>
public class BackgroundWorkerQueue
/// <summary>Continue running BackgroundWorkerQueue if any BackgroundWorker causes an Exception.</summary>
public bool ContinueOnError get; set;
private Queue<QueuedWorker> Queue get; set;
public BackgroundWorkerQueue( )
this.Queue = new Queue<QueuedWorker>();
public static BackgroundWorkerQueue operator +( BackgroundWorkerQueue left, BackgroundWorker worker )
left.Add(worker);
return left;
public static BackgroundWorkerQueue operator +( BackgroundWorkerQueue left, QueuedWorker worker )
left.Add(worker);
return left;
/// <summary>Add a BackgroundWorker to the Queue</summary>
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
/// <param name="argument">A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</param>
public void Add( BackgroundWorker worker, object argument )
this.Queue.Enqueue(new QueuedWorker(worker,argument));
/// <summary>Add a BackgroundWorker to the Queue</summary>
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
public void Add( BackgroundWorker worker )
this.Queue.Enqueue(new QueuedWorker(worker,null));
/// <summary>Add a BackgroundWorker to the Queue</summary>
public void Add( QueuedWorker worker )
this.Queue.Enqueue(worker);
/// <summary>Starts execution of the BackgroundWorkers.</summary>
public void Run( )
Debug.Print("BackgroundWorkerQueue.Run(), 0 items in queue.", this.Queue.Count);
QueuedWorker q = this.Queue.Dequeue();
q.Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.Completed);
q.Worker.RunWorkerAsync(q.Argument);
private void Completed( object sender, RunWorkerCompletedEventArgs e )
Debug.Print("BackgroundWorkerQueue.Completed()");
BackgroundWorker worker = sender as BackgroundWorker;
if( worker != null )
/// <summary>Object containing a BackgroundWorker and optional Argument to be run.</summary>
public class QueuedWorker
/// <summary></summary>A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</summary>
public object Argument get; set;
/// <summary>BackgroundWorker to be run.</summary>
public BackgroundWorker Worker get; set;
public QueuedWorker()
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
/// <param name="argument">A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</param>
public QueuedWorker( BackgroundWorker worker, object argument )
this.Worker = worker;
this.Argument = argument;
Example Usage:
var q = new BackgroundWorkerQueue();
q.Add(InventoryBgWorker,"FIN STOCK"); // to add a worker, you can call one of the Add(...) methods
q += PartDataBgWorker; // or you can use the += operator
q += OpenOrdersBgWorker;
q.Run(); // Does not block current thread.
c# multithreading .net queue
You could consider creating class that converts/wraps the background workers using TPL (Task / TaskCompletionSource) and then await the workers.Task.WhenAll
can also be used to run them simultaneously.
â Nkosi
Jan 6 at 2:13
1
Or foregoing the background workers altogether and use Tasks blog.stephencleary.com/2013/05/⦠and blog.stephencleary.com/2013/09/â¦
â Nkosi
Jan 6 at 4:46
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
In my project, I had three BackgroundWorker
s that can be run independently, but I also wanted to allow the user to "Run All" of them, but not at the same time. They need to be run one after the other. So, I devised this class
to create a Queue
of BackgroundWorker
s, subscribe to their RunWorkerCompleted
event handler, and run the next worker in the Queue
.
I would like to know:
- If this is even a good idea
- If there are any potential bugs I might have overlooked
- If I've violated any normal .Net conventions.
- Any ways to improve the functionality, speed, or readability of the code
/// <summary>
/// Simplifies running a Queue of BackgroundWorkers one after the other without blocking the current thread.
/// </summary>
public class BackgroundWorkerQueue
/// <summary>Continue running BackgroundWorkerQueue if any BackgroundWorker causes an Exception.</summary>
public bool ContinueOnError get; set;
private Queue<QueuedWorker> Queue get; set;
public BackgroundWorkerQueue( )
this.Queue = new Queue<QueuedWorker>();
public static BackgroundWorkerQueue operator +( BackgroundWorkerQueue left, BackgroundWorker worker )
left.Add(worker);
return left;
public static BackgroundWorkerQueue operator +( BackgroundWorkerQueue left, QueuedWorker worker )
left.Add(worker);
return left;
/// <summary>Add a BackgroundWorker to the Queue</summary>
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
/// <param name="argument">A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</param>
public void Add( BackgroundWorker worker, object argument )
this.Queue.Enqueue(new QueuedWorker(worker,argument));
/// <summary>Add a BackgroundWorker to the Queue</summary>
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
public void Add( BackgroundWorker worker )
this.Queue.Enqueue(new QueuedWorker(worker,null));
/// <summary>Add a BackgroundWorker to the Queue</summary>
public void Add( QueuedWorker worker )
this.Queue.Enqueue(worker);
/// <summary>Starts execution of the BackgroundWorkers.</summary>
public void Run( )
Debug.Print("BackgroundWorkerQueue.Run(), 0 items in queue.", this.Queue.Count);
QueuedWorker q = this.Queue.Dequeue();
q.Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.Completed);
q.Worker.RunWorkerAsync(q.Argument);
private void Completed( object sender, RunWorkerCompletedEventArgs e )
Debug.Print("BackgroundWorkerQueue.Completed()");
BackgroundWorker worker = sender as BackgroundWorker;
if( worker != null )
/// <summary>Object containing a BackgroundWorker and optional Argument to be run.</summary>
public class QueuedWorker
/// <summary></summary>A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</summary>
public object Argument get; set;
/// <summary>BackgroundWorker to be run.</summary>
public BackgroundWorker Worker get; set;
public QueuedWorker()
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
/// <param name="argument">A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</param>
public QueuedWorker( BackgroundWorker worker, object argument )
this.Worker = worker;
this.Argument = argument;
Example Usage:
var q = new BackgroundWorkerQueue();
q.Add(InventoryBgWorker,"FIN STOCK"); // to add a worker, you can call one of the Add(...) methods
q += PartDataBgWorker; // or you can use the += operator
q += OpenOrdersBgWorker;
q.Run(); // Does not block current thread.
c# multithreading .net queue
In my project, I had three BackgroundWorker
s that can be run independently, but I also wanted to allow the user to "Run All" of them, but not at the same time. They need to be run one after the other. So, I devised this class
to create a Queue
of BackgroundWorker
s, subscribe to their RunWorkerCompleted
event handler, and run the next worker in the Queue
.
I would like to know:
- If this is even a good idea
- If there are any potential bugs I might have overlooked
- If I've violated any normal .Net conventions.
- Any ways to improve the functionality, speed, or readability of the code
/// <summary>
/// Simplifies running a Queue of BackgroundWorkers one after the other without blocking the current thread.
/// </summary>
public class BackgroundWorkerQueue
/// <summary>Continue running BackgroundWorkerQueue if any BackgroundWorker causes an Exception.</summary>
public bool ContinueOnError get; set;
private Queue<QueuedWorker> Queue get; set;
public BackgroundWorkerQueue( )
this.Queue = new Queue<QueuedWorker>();
public static BackgroundWorkerQueue operator +( BackgroundWorkerQueue left, BackgroundWorker worker )
left.Add(worker);
return left;
public static BackgroundWorkerQueue operator +( BackgroundWorkerQueue left, QueuedWorker worker )
left.Add(worker);
return left;
/// <summary>Add a BackgroundWorker to the Queue</summary>
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
/// <param name="argument">A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</param>
public void Add( BackgroundWorker worker, object argument )
this.Queue.Enqueue(new QueuedWorker(worker,argument));
/// <summary>Add a BackgroundWorker to the Queue</summary>
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
public void Add( BackgroundWorker worker )
this.Queue.Enqueue(new QueuedWorker(worker,null));
/// <summary>Add a BackgroundWorker to the Queue</summary>
public void Add( QueuedWorker worker )
this.Queue.Enqueue(worker);
/// <summary>Starts execution of the BackgroundWorkers.</summary>
public void Run( )
Debug.Print("BackgroundWorkerQueue.Run(), 0 items in queue.", this.Queue.Count);
QueuedWorker q = this.Queue.Dequeue();
q.Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.Completed);
q.Worker.RunWorkerAsync(q.Argument);
private void Completed( object sender, RunWorkerCompletedEventArgs e )
Debug.Print("BackgroundWorkerQueue.Completed()");
BackgroundWorker worker = sender as BackgroundWorker;
if( worker != null )
/// <summary>Object containing a BackgroundWorker and optional Argument to be run.</summary>
public class QueuedWorker
/// <summary></summary>A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</summary>
public object Argument get; set;
/// <summary>BackgroundWorker to be run.</summary>
public BackgroundWorker Worker get; set;
public QueuedWorker()
/// <param name="worker">BackgroundWorker to call RunWorkerAsync() on.</param>
/// <param name="argument">A parameter for use by the background operation to be executed in the System.ComponentModel.BackgroundWorker.DoWork event handler.</param>
public QueuedWorker( BackgroundWorker worker, object argument )
this.Worker = worker;
this.Argument = argument;
Example Usage:
var q = new BackgroundWorkerQueue();
q.Add(InventoryBgWorker,"FIN STOCK"); // to add a worker, you can call one of the Add(...) methods
q += PartDataBgWorker; // or you can use the += operator
q += OpenOrdersBgWorker;
q.Run(); // Does not block current thread.
c# multithreading .net queue
edited Jan 30 at 1:15
Jamalâ¦
30.1k11114225
30.1k11114225
asked Jan 5 at 16:40
Drew Chapin
799719
799719
You could consider creating class that converts/wraps the background workers using TPL (Task / TaskCompletionSource) and then await the workers.Task.WhenAll
can also be used to run them simultaneously.
â Nkosi
Jan 6 at 2:13
1
Or foregoing the background workers altogether and use Tasks blog.stephencleary.com/2013/05/⦠and blog.stephencleary.com/2013/09/â¦
â Nkosi
Jan 6 at 4:46
add a comment |Â
You could consider creating class that converts/wraps the background workers using TPL (Task / TaskCompletionSource) and then await the workers.Task.WhenAll
can also be used to run them simultaneously.
â Nkosi
Jan 6 at 2:13
1
Or foregoing the background workers altogether and use Tasks blog.stephencleary.com/2013/05/⦠and blog.stephencleary.com/2013/09/â¦
â Nkosi
Jan 6 at 4:46
You could consider creating class that converts/wraps the background workers using TPL (Task / TaskCompletionSource) and then await the workers.
Task.WhenAll
can also be used to run them simultaneously.â Nkosi
Jan 6 at 2:13
You could consider creating class that converts/wraps the background workers using TPL (Task / TaskCompletionSource) and then await the workers.
Task.WhenAll
can also be used to run them simultaneously.â Nkosi
Jan 6 at 2:13
1
1
Or foregoing the background workers altogether and use Tasks blog.stephencleary.com/2013/05/⦠and blog.stephencleary.com/2013/09/â¦
â Nkosi
Jan 6 at 4:46
Or foregoing the background workers altogether and use Tasks blog.stephencleary.com/2013/05/⦠and blog.stephencleary.com/2013/09/â¦
â Nkosi
Jan 6 at 4:46
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
4
down vote
You can forego the background workers in favor of Tasks either via Task.Run
or just async functions. They can be run independently, all at once or sequentially.
The following example takes a collection of tasks and invokes them one after the other.
//Assuming all the following return Task derived results
var tasks = new Func<Task>
() => InventoryService.GetInventoryAsync("FIN STOCK"),
() => PartsService.GetPartDataAsync(),
() => OrdersService.OpenOrderAsync()
;
Debug.Print("RunAllAsync(), 0 items in collection.", tasks.Length);
foreach (var task in tasks)
try
await task();
catch (Exception e)
if (ContinueOnError)
continue;
else
break;
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
You can forego the background workers in favor of Tasks either via Task.Run
or just async functions. They can be run independently, all at once or sequentially.
The following example takes a collection of tasks and invokes them one after the other.
//Assuming all the following return Task derived results
var tasks = new Func<Task>
() => InventoryService.GetInventoryAsync("FIN STOCK"),
() => PartsService.GetPartDataAsync(),
() => OrdersService.OpenOrderAsync()
;
Debug.Print("RunAllAsync(), 0 items in collection.", tasks.Length);
foreach (var task in tasks)
try
await task();
catch (Exception e)
if (ContinueOnError)
continue;
else
break;
add a comment |Â
up vote
4
down vote
You can forego the background workers in favor of Tasks either via Task.Run
or just async functions. They can be run independently, all at once or sequentially.
The following example takes a collection of tasks and invokes them one after the other.
//Assuming all the following return Task derived results
var tasks = new Func<Task>
() => InventoryService.GetInventoryAsync("FIN STOCK"),
() => PartsService.GetPartDataAsync(),
() => OrdersService.OpenOrderAsync()
;
Debug.Print("RunAllAsync(), 0 items in collection.", tasks.Length);
foreach (var task in tasks)
try
await task();
catch (Exception e)
if (ContinueOnError)
continue;
else
break;
add a comment |Â
up vote
4
down vote
up vote
4
down vote
You can forego the background workers in favor of Tasks either via Task.Run
or just async functions. They can be run independently, all at once or sequentially.
The following example takes a collection of tasks and invokes them one after the other.
//Assuming all the following return Task derived results
var tasks = new Func<Task>
() => InventoryService.GetInventoryAsync("FIN STOCK"),
() => PartsService.GetPartDataAsync(),
() => OrdersService.OpenOrderAsync()
;
Debug.Print("RunAllAsync(), 0 items in collection.", tasks.Length);
foreach (var task in tasks)
try
await task();
catch (Exception e)
if (ContinueOnError)
continue;
else
break;
You can forego the background workers in favor of Tasks either via Task.Run
or just async functions. They can be run independently, all at once or sequentially.
The following example takes a collection of tasks and invokes them one after the other.
//Assuming all the following return Task derived results
var tasks = new Func<Task>
() => InventoryService.GetInventoryAsync("FIN STOCK"),
() => PartsService.GetPartDataAsync(),
() => OrdersService.OpenOrderAsync()
;
Debug.Print("RunAllAsync(), 0 items in collection.", tasks.Length);
foreach (var task in tasks)
try
await task();
catch (Exception e)
if (ContinueOnError)
continue;
else
break;
edited Jan 29 at 19:34
answered Jan 6 at 4:59
Nkosi
1,870619
1,870619
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184377%2frunning-a-collection-of-backgroundworkers-one-after-the-other%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
You could consider creating class that converts/wraps the background workers using TPL (Task / TaskCompletionSource) and then await the workers.
Task.WhenAll
can also be used to run them simultaneously.â Nkosi
Jan 6 at 2:13
1
Or foregoing the background workers altogether and use Tasks blog.stephencleary.com/2013/05/⦠and blog.stephencleary.com/2013/09/â¦
â Nkosi
Jan 6 at 4:46