Search code examples
c#.netbackgroundworker

Multi-BackgroundWorker


How to know when all workers from loop are finished? And how to "execute" bw_RunWorkerCompleted after all that workers. I have tried in several ways but I failed. The main worker always finish first.

.Net 3.5

http://pastebin.com/kMmajq6f

using System;
using System.ComponentModel;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            BackgroundWorker bw = new BackgroundWorker();
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
            bw.WorkerSupportsCancellation = true;
            bw.WorkerReportsProgress = true;

            bw.RunWorkerAsync();

            Console.ReadLine();

        }

        static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine("All");
        }

        static void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                BackgroundWorker inBW = new BackgroundWorker();
                inBW.DoWork += new DoWorkEventHandler(inBW_DoWork);
                inBW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(inBW_RunWorkerCompleted);

                inBW.RunWorkerAsync(i.ToString());
            }
        }

        static void inBW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Console.WriteLine(e.Result as String);
        }

        static void inBW_DoWork(object sender, DoWorkEventArgs e)
        {
            Thread.Sleep(new Random().Next(1000, 5000));

            e.Result = e.Argument as string;
        }
    }
}

Solution

  • The RunWorkerCompleted event handler is called once the DoWork event handler returns. In this case the bw_DoWork method returns once it spins off 10 additional BackgroundWorkers.

    I was going to suggest you use a CountdownEvent for your case but realized you're on .Net 3.5. In that case you can create something similar using Pulse and Wait.