Thread.Join will mean the main thread will block until all threads that have
been used in Thread.Join calls, terminate. Which will do what you want. If
that main thread is doing any GUI work; your program will look unresponsive
(I think you said you abstracted it away from a Form class; so, I assume this
"main" thread is another background thread, which I refer to as the "host"
thread).
I would suggest, if you're using VS2005/.NET2.0, that you use the
BackgroundWorker class. It uses the an updated asynchronous model (via
events, rather than a call back) and manages calling the events (at least the
progress and the completed events) on the thread that started the
asynchronous operation, not the thread that is performing the background
operation.
I don't think you need to worry whether the background thread is still
"alive", just whether it's operation is completed or not. The drawback of
using something like BackgroundWorker, as you've noticed with asynchronous
delegates, is you need some way of managing the state of all those
operations. This could simply be an array of WaitHandles for which a call to
WaitHandle.WaitAll is made in the host thread to tell when all operations
have completed. The BackgroundWorker.RunWorkerCompleted event would simply
signal that WaitHandle object.
--
http://www.peterRitchie.com/
"Peter Ritchie" wrote:
[color=blue]
> A general rule of thumb: if the concept/method exists in .NET 1.1 then the
> callback/event-handler is being called using the background thread. This is
> the case for asynchronous delegates, they're called using the background
> thread, not the thread that invoked the delegate.
>
> In .NET 2.0 you can use the AsyncOperationManager class to make sure async
> callbacks are called using a particular thread.
>
> Even if you call your AsyncCallback on the "main" thread, you're still going
> to be in a situation where the thread that instigates the callback is still
> technically running when the callback is called. In the case of async
> delegates this callback means the method has finished executing; it doesn't
> mean the thread has finished executing.
>
> The only way to know if a thread has terminated (without polling) is if you
> use Thread.Join, something that you can't use with thread pool threads. In
> your case, I don't know why you'd want to make the distinction of when the
> task is completed and when the thread has terminated...
>
> Another thing I should point out is when to use multiple threads. There's
> really only three reliable scenarios for multiple threads. One scenario is:
> you want to spawn a single thread to do work because another thread that does
> not use much of the CPU needs to be active. This includes spawning
> background threads from a GUI thread to keep the GUI responsive. A second
> scenario is if you want to take advantage of multi-processor or
> multi-core-processors. The third scenario is you want to wait for something
> to complete (like asynchronous IO) without blocking another thread.
>
> If you spawn more than one thread on a single processor, single-core
> processor, then you're actually slowing your program down. Your program is
> now using more system resources, asking the system to manage your threads
> (time-slicing between them, incurring a context switch), and adding
> processing to start and wait for the threads. All of which take processing
> time.
>
> --
>
http://www.peterRitchie.com/
>
>
> "Bryce K. Nielsen" wrote:
>[color=green][color=darkred]
> > > How are you keeping track of each thread?
> > >[/color]
> >
> > The main process has a list of objects that are associated with each
> > thread/delegate. In this object is a flag set at the end of the process, and
> > then the AsyncCallback from the main process checks the list of processes to
> > see if they're all completed. If they are, continue processing, otherwise do
> > nothing and wait until it's called again by another completing thread.
> >[color=darkred]
> > > Normally, if the continuation of one thread is Dependant on one or more
> > > other threads you would call Thread.Join() for each thread
> > > object--something
> > > you can't do with thread pool threads.
> > >[/color]
> >
> > Well, previously I had all my code on the Form executing stuff, so at the
> > end (after the AsyncCallback was called and all objects.Completed flag was
> > true) I would call Form.Invoke and this would continue processing back on
> > the original/Form thread. However, I recently decoupled the main process
> > from the Form onto it's own Thread object. So, since this object is not a
> > Control, it has no Invoke() method. So I'm afraid that at the end, the
> > process is picking up on the last-executed thread, instead of giving control
> > back to the main process thread.
> >
> > So Thread.Join() would allow me to pick back up on the main thread?
> >
> > -BKN
> >
> >
> >[/color][/color]