0

I've built a C# Winforms app that serves as a simulation to run a set of tasks that are computationally and memory intensive. I'm using a background worker to do the work so the UI can remain responsive. I've got just a for loop:

var iterations = Convert.ToInt32(txtNumIterations.Text);
for (int i = 0; i < iterations; i++)
{
ResetSim();
StartWorker("RunSimulation", i + 1);
}

What I would like is to just run these sequentially in the background, but I can't figure out if a background worker set up will do this, or if I need to use Tasks. I haven't found a really good example that explains how a Task could accomplish my goal. Any help would be appreciated.

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272

3 Answers3

0

If you need to run your simulations sequentially then you can subscribe to the background workers RunWorkerCompleted event to start the next one.

So you just start the first worker off:

var worker1 = new BackgroundWorker();
worker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
worker1.RunWorkerAsync();

Then in the handler:

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    var worker2 = new BackgroundWorker();
    worker2.RunWorkerCompleted += backgroundWorker2_RunWorkerCompleted;
    worker2.RunWorkerAsync();
}

Obviously you can use an array to hold the references to each worker and have a class variable to hold which one's active. You'd then only need one handler to increment the simulation count and start the next one in the list.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • Then what's the point of using BackGroundWorker at all. Why not just run all the method/actions in classic synchronous fashion. – Rahul Jun 19 '16 at 21:21
  • @Rahul - well you might want the UI to be responsive while processing so you can do other tasks, cancel the simulation etc. – ChrisF Jun 19 '16 at 21:23
0

You can use the BackgroundWorker.ReportProgress Method in the DoWork method in order to pass back information to the main thread. You could do the loop in the DoWork method and at each loop call worker.ReportProgress(i); with the loop variable. The value is not interpreted by the background worker, so it needs not to be a percentage value. Then in the ProgressChanged event handler you can call ResetSim();. (I assume that ResetSim acts in the UI and must therefore be executed on the UI thread.)

Community
  • 1
  • 1
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
0

From your description it sounds like you really don't need multiple background workers, just use a single background worker and run the loop inside of it.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431