I've never really used threading before in C# where I need to have two threads, as well as the main UI thread. Basically, I have the following.
public void StartTheActions()
{
//Starting thread 1....
Thread t1 = new Thread(new ThreadStart(action1));
t1.Start();
// Now, I want for the main thread (which is calling `StartTheActions` method)
// to wait for `t1` to finish. I've created an event in `action1` for this.
// The I wish `t2` to start...
Thread t2 = new Thread(new ThreadStart(action2));
t2.Start();
}
So, essentially, my question is how to have a thread wait for another one to finish. What is the best way to do this?
The previous two answers are great, and will work for simple scenarios. There are other ways to synchronize threads, however. The following will also work:
ManualResetEvent is one of the various WaitHandle's that the .NET framework has to offer. They can provide much richer thread synchronization capabilities than the simple but very common tools like lock()/Monitor, Thread.Join, etc. They can also be used to synchronize more than two threads, allowing complex scenarios such as a 'master' thread that coordinates multiple 'child' threads, multiple concurrent processes that are dependent upon several stages of each other to be synchronized, etc.
You want the
Thread.Join()
method, or one of its overloads.I can see 5 options available:
1. Thread.Join
As with Mitch's answer. But this will block your UI thread, however you get a Timeout built in for you.
2. Use a
WaitHandle
ManualResetEvent
is aWaitHandle
as jrista suggested.One thing to note is if you want to wait for multiple threads,
WaitHandle.WaitAll()
won't work by default, as it needs an MTA thread. You can get around this by marking yourMain()
method withMTAThread
- however this blocks your message pump and isn't recommended from what I've read.3. Fire an event
See this page by Jon Skeet about events and multi-threading, it's possible that an event can become unsubcribed between the
if
and theEventName(this,EventArgs.Empty)
- it's happened to me before.(Hopefully these compile, I haven't tried)
4. Use a delegate
If you do use the _count method, it might be an idea (to be safe) to increment it using
Interlocked.Increment(ref _count)
I'd be interested to know the difference between using delegates and events for thread notification, the only difference I know are events are called synchronously.
5. Do it asynchronously instead
The answer to this question has a very clear description of your options with this method.
Delegate/Events on the wrong thread
The event/delegate way of doing things will mean your event handler method is on thread1/thread2 not the main UI thread, so you will need to switch back right at the top of the HandleThreadDone methods:
If using from .NET 4 this sample can help you:
from: https://stackoverflow.com/a/4190969/1676736
Posting to maybe help some others, spent quite a bit of time looking for a solution like what I came up with. So I took a little different approach. There is a counter option above, I just applied it a bit differently. I was spinning off numerous threads and incremented a counter and decremented a counter as a thread started and stopped. Then in the main method I was wanting to pause and wait for threads to complete I did.
Documented on my blog. http://www.adamthings.com/post/2012/07/11/ensure-threads-have-finished-before-method-continues-in-c/
Try this: