On Thu, 14 Jun 2007 17:54:49 -0700, cyrous xiao
<cy*********@ma esinfo.com.cnwr ote:
[...]
Thread ThreadDialog= new Thread (new ThreadStart (ShowDialog));
//Show a winform Dialog
ThreadDialog.St art ();
Thread Thread1= new Thread (new ThreadStart (Thread1Func));
Thread1.Start ();
Thread Thread2= new Thread (new ThreadStart (Thread2Func));
Thread2.Start ();
Thread Thread3= new Thread (new ThreadStart (Thread3Func));
Thread3.Start ();
Now I want to close the dialog when the three thread all closed.How did I
do.
Well, the first step is to not show your dialog in a new thread. Keep all
your form instances in the same thread, mainly because it's simpler and
there's no good reason to do it otherwise.
Then you need a way for each of the three threads to signal their
completion to the form you've shown. There are a variety of ways to do
this, but it seems to me that a reasonable way is to maintain a counter
representing the threads and have each thread decrement the counter. If
and when it reaches 0, then close the form (warning: uncompiled code,
could have errors, but hopefully you get the basic idea):
class MyDialog : Form
{
private int _cthread;
protected override void OnLoad(object sender, EventArgs a)
{
InitThreads();
}
// Here we initialize our counter and start our threads
void InitThreads()
{
_cthread = 3;
(new Thread(new ThreadStart(Thr ead1Func))).Sta rt();
(new Thread(new ThreadStart(Thr ead2Func))).Sta rt();
(new Thread(new ThreadStart(Thr ead3Func))).Sta rt();
}
// This is the method that each thread uses Invoke() with to
decrement
// the counter. When the counter reaches 0, that's the last
thread and
// it's time to close the form.
void ThreadFinished( )
{
if (--_cthread == 0)
{
Close();
}
}
void Thread1Func()
{
// Do some work
// Here's the magic:
// The Control.Invoke( ) method causes a delegate to be
executed on
// the same thread that owns the Control instance (this
form, in this
// case). This has a couple of advantages for this
purpose: first,
// access to the _cthread field is restricted to a single
thread, allowing
// synchronized access; also, it allows the thread thatis
the last to
// finish to actually close the the form (the Close()
method must be
// called from within the thread that owns the Control)..
Invoke(new MethodInvoker(T hreadFinished)) ;
}
// Thread2Func and Thread3Func are implemented similarly
}
Then in whatever code, you just have to display the dialog:
MyDialog dlg = new MyDialog();
dlg.ShowDialog( );
Note: the above code puts the thread control code into the dialog class.
It's nice to put it there so that the presentation of the dialog is
synchronized with the execution of the threads. Because Form.ShowDialog ()
doesn't return until the dialog has been closed, you can't start the
threads after calling ShowDialog(). But if you start the threads before
calling ShowDialog() there's a risk that one or more threads might
complete before the dialog even is shown (a very slight risk, to be sure,
and maybe not possible in practice, but even a theoretical possibility is
worth designing for). IMHO, the most straight-forward way to deal with
this is to just put the thread initialization into the dialog itself.
Hope that helps.
Pete