C# Multiple BackgroundWorkers
backgroundworker, c#
Solution
The problem appears to be that your workers are never completing. Why this is, I'm not sure; it has something to do with the fact that the method (and thread) you are running them from is not itself completing. I was able to solve the problem by creating another worker to assign files to the worker array:
private BackgroundWorker assignmentWorker;
private void InitializeBackgoundWorkers() {
assignmentWorker = new BackgroundWorker();
assignmentWorker.DoWork += AssignmentWorkerOnDoWork;
// ...
}
private void AssignmentWorkerOnDoWork( object sender, DoWorkEventArgs doWorkEventArgs ) {
for( var f = 0; f < FilesToProcess; f++ ) {
var fileProcessed = false;
while( !fileProcessed ) {
for( var threadNum = 0; threadNum < MaxThreads; threadNum++ ) {
if( !threadArray[threadNum].IsBusy ) {
Console.WriteLine( "Starting Thread: {0}", threadNum );
threadArray[threadNum].RunWorkerAsync( f );
fileProcessed = true;
break;
}
}
if( !fileProcessed ) {
Thread.Sleep( 50 );
break;
}
}
}
}
private void button1_Click( object sender, EventArgs e ) {
assignmentWorker.RunWorkerAsync();
}
I'm not happy with this answer because I don't know why, exactly, it didn't work as you originally designed it. Perhaps someone else can answer that...? At least this will get you a working version.
EDIT: Your original version didn't work because the `BackgroundWorkerFilesRunWorkerCompleted` runs on the same thread as `button1_Click` (the UI thread). Since you are not freeing up the UI thread, the thread is never getting marked as complete.
Problem
I am trying to setup multiple `BackgroundWorker`s to do work and when not busy start doing the next bit of work. I can't seem to get them working properly. I have the below code. When I set `FilesToProcess` equal or less than `MaxThreads` it works perfectly although if I make it higher, the app freezes. I am sure it is something simple, but I just can't see it. ``` using System; using System.ComponentModel; using System.Threading; using System.Windows.Forms; namespace bgwtest { public partial class Form1 : Form { private const int MaxThreads = 20; private const int FilesToProcess = 21; private BackgroundWorker[] threadArray = new BackgroundWorker[MaxThreads]; public Form1() { InitializeComponent(); } private void Form1Load(object sender, EventArgs e) { InitializeBackgoundWorkers(); } private void InitializeBackgoundWorkers() { for (var f = 0; f < MaxThreads; f++) { threadArray[f] = new BackgroundWorker(); threadArray[f].DoWork += new DoWorkEventHandler(BackgroundWorkerFilesDoWork); threadArray[f].RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorkerFilesRunWorkerCompleted); threadArray[f].WorkerReportsProgress = true; threadArray[f].WorkerSupportsCancellation = true; } } private void button1_Click(object sender, EventArgs e) { for (var f = 0; f < FilesToProcess; f++) { var fileProcessed = false; while (!fileProcessed) { for (var threadNum = 0; threadNum < MaxThreads; threadNum++) { if (!threadArray[threadNum].IsBusy) { Console.WriteLine("Starting Thread: {0}", threadNum); threadArray[threadNum].RunWorkerAsync(f); fileProcessed = true; break; } } if (!fileProcessed) { Thread.Sleep(50); } } } } private void BackgroundWorkerFilesDoWork(object sender, DoWorkEventArgs e) { ProcessFile((int)e.Argument); e.Result = (int)e.Argument; } private static void ProcessFile(int file) { Console.WriteLine("Processing File: {0}", file); } private void BackgroundWorkerFilesRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Error != null) { MessageBox.Show(e.Error.Message); } Console.WriteLine("Processed File: {0}", (int)e.Result); } } } ```