To answer your question about using specifically four threads, below is a quick sketch using BackgroundWorker. The idea here is to set up four tasks, track the number of running tasks and, when they're all done restart. For a discussion of volatile vs interlocked, see Stack Overflow question Volatile vs. Interlocked vs. lock.
This will give you what you're asking for (four threads, responsive UI), but there's no error handling, and there could be other problems. Is it possible that one BackgroundWorker would hang (maybe your 'data transmission' goes haywire) in which case you'll end up in a bad state?
public partial class Form1 : Form {
private int workersRunning = 0;
private List<BackgroundWorker> workers = new List<BackgroundWorker>();
public Form1() {
InitializeComponent();
for (int i = 0; i < 4; i++) {
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(this.worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.worker_RunWorkerCompleted);
workers.Add(worker);
}
}
private void button1_Click(object sender, EventArgs e) {
this.StartWork();
}
private void StartWork() {
workers.ForEach(worker => worker.RunWorkerAsync());
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){
Interlocked.Decrement(ref workersRunning);
Console.WriteLine("Worker reported completion from thread id " + e.Result);
if(this.workersRunning == 0) {
Console.WriteLine("All workers are done. Start again");
this.StartWork();
} else {
Console.WriteLine(this.workersRunning + " workers are still running.");
}
}
void worker_DoWork(object sender, DoWorkEventArgs e) {
Interlocked.Increment(ref workersRunning);
int threadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("Doing work on thread #" + threadId);
Thread.Sleep(new Random().Next(2000, 5000));
e.Result = "Work done on thread id " + threadId;
}
}