One way I have figured out is to store the BackgroundWorkers in a
collection and keep checking their IsBusy property. I am still not sure
if this is the best way to do it. I would really appreciate some help.

So in the code below, I execute a long running operation 10 times; there
is a synchronous version, and then there is an asynchronous version
using BackgroundWorkers? Do you see any problems in using the
BackgroundWorkers this way?

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Threading;
using System.Collections;

namespace BackgroundWorkerDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime start_time = DateTime.Now;

            Console.WriteLine("Program starting");

            //RunSyncVersion();
            RunAsyncVersion();

            DateTime end_time = DateTime.Now;

            TimeSpan ts = end_time - start_time;

            Console.WriteLine("Program completed. Duration={0}
seconds.", ts.Seconds);
            Console.Read();
        }

        static void worker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
        {
            
        }

        //Synchronous version
        static void RunSyncVersion()
        {
            for (int i = 0; i <= 10; i++)
            {
                LongRunningOperation(i);
            }
        }

        //This version uses the async version
        static void RunAsyncVersion()
        {
            ArrayList lstBGWs = new ArrayList();

            for (int i = 0; i <= 10; i++)
            {
                BackgroundWorker worker = new BackgroundWorker();

                worker.DoWork += new DoWorkEventHandler(worker_DoWork);

                worker.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

                lstBGWs.Add(worker);

                worker.RunWorkerAsync(i);
            }

            bool all_workers_have_returned = false;

            while (all_workers_have_returned == false)
            {
                all_workers_have_returned = true;

                foreach (BackgroundWorker worker in lstBGWs)
                {
                    if (worker.IsBusy == true)
                    {
                        all_workers_have_returned = false;

                        break;
                    }
                }
            }
        }

        static void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            LongRunningOperation(Convert.ToInt32(e.Argument));
        }

        //Long running operation
        private static void LongRunningOperation(int operation_number)
        {
            Console.WriteLine("Operation# {0} starting on Thread {1}",
operation_number, Thread.CurrentThread.ManagedThreadId);
            for (int i=0; i < 1000000000; i++)
            {

            }

            Console.WriteLine("Finished operation# {0} on Thread {1}",
operation_number, Thread.CurrentThread.ManagedThreadId);
        }
    }
}

-----Original Message-----
From: Discussion of advanced .NET topics.
[mailto:[EMAIL PROTECTED] On Behalf Of Greg Young
Sent: Thursday, July 19, 2007 1:53 PM
To: ADVANCED-DOTNET@DISCUSS.DEVELOP.COM
Subject: Re: [ADVANCED-DOTNET] Question about the right way to use
BackGroundWorker

Why not use ThreadPool.QueueUserWorkItem each with its own event it sets
then use WaitHandle.WaitAll(WaitHandle[] waitHandles) as opposed to
creating a new thread for each?


http://www.codeproject.com/csharp/eventsthreadsync.asp is an example of
events http://msdn2.microsoft.com/en-us/library/27y100eh.aspx is the
overload you probably want to use (supports a timeout) the page also
includes an example (using the threadpool).

Cheers,

Greg Young

On 7/19/07, Peter Ritchie
<[EMAIL PROTECTED]> wrote:
> You can't.  The default behaviour of BackgroundWorker is the raise the

> progress and completed events on the thread that created 
> BackgroundWorker.  If you block the thread until DoSomething returns 
> the Completed and Progress event's will never get the thread need to 
> raise them.  You'd be deadlocked.
>
> On Thu, 19 Jul 2007 10:57:25 -0700, Chopra, Arvinder [Beeline] 
> <[EMAIL PROTECTED]> wrote:
>
> >Consider this pseudocode:
> >
> >Public void DoSomething()
> >{
> >  Foreach (pending_job job in ListOfPendingJobs)
> >  {
> >        job.ExecuteLongOperation();
> >  }
> >
> >  Return to caller;
> >}
> >
> >What I want to do is to execute the job.ExecuteLongOperation() on a 
> >separate thread using BackGroundWorker(). The question is what is the

> >best practice/pattern to make sure all BackGroundWorkers have 
> >finished execution before the above method returns.
>
> ===================================
> This list is hosted by DevelopMentor(r)  http://www.develop.com
>
> View archives and manage your subscription(s) at 
> http://discuss.develop.com
>


--
Studying for the Turing test

===================================
This list is hosted by DevelopMentor(r)  http://www.develop.com

View archives and manage your subscription(s) at
http://discuss.develop.com

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to