Boris Callens
Boris Callens

Reputation: 93287

Wait for two threads to finish

If you have one main thread that starts two other threads. what is the cleanest way to make the primary thread wait for the two other threads?

I could use bgndworker and sleep spinner that checks for both the bgnd workers's IsBusy, but I would think there's a better way.

EDIT Some more requirements:

Upvotes: 3

Views: 12194

Answers (6)

Migol
Migol

Reputation: 8448

You can't wait for finish and have GUI usable. The best approach for this is to spawn threads and use events to communicate with GUI. Remember, that in the event handler you cannot modify control. Rather that doing it directly, use Invoke method.

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1062520

See the answers on this thread. I like this option ;-p

Forker p = new Forker();
p.Fork(delegate { DoSomeWork(); });
p.Fork(delegate { DoSomeOtherWork(); });
p.Join();

Re returning values / reporting exceptions - just have each fork do that as a callback at the end of the logic... (you can use captured variables to pass state into both the forks, including a shared logger etc).

Upvotes: 5

Jon Skeet
Jon Skeet

Reputation: 1499740

In addition to the other answers... one alternative to "start two threads and wait for both to finish" is "start one thread and do one job yourself, then wait for the other thread to finish".

Of course, if you want to start two jobs, do some more work on the main thread and then wait for the two other threads to finish, that doesn't work so well.

EDIT: If the main thread is a UI thread, you shouldn't be blocking on the other threads finishing - you should (IMO) get them to call back to the main thread when they've finished. That way you'll still have a responsive UI while they're executing.

Upvotes: 1

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93424

WaitHandle.WaitAny is your friend. It lets you wait on multiple threads or other kinds of objects to be signaled.

http://msdn.microsoft.com/en-us/library/tdykks7z.aspx

EDIT:

Actually, WaitHandle.WaitAll is what you want, not WaitAny.

http://msdn.microsoft.com/en-us/library/system.threading.waithandle.waitall.aspx

EDIT:

The Join method some mention is ok, but one drawback is that it's not an completely atomic operation. This may or may not be important to you, though.

Upvotes: 0

REA_ANDREW
REA_ANDREW

Reputation: 10764

Quick example using Thread.Join();

        Thread t1 = new Thread(new ThreadStart(delegate()
        {
            System.Threading.Thread.Sleep(2000);
        }));

        Thread t2 = new Thread(new ThreadStart(delegate()
        {
            System.Threading.Thread.Sleep(4000);
        }));

        t1.Start();
        t2.Start();

        t1.Join();
        t2.Join();

EDIT Another 3example using Wait Handles:

            ManualResetEvent[] waitHandles = new ManualResetEvent[]{
            new ManualResetEvent(false),
            new ManualResetEvent(false)
        };

        Thread t1 = new Thread(new ParameterizedThreadStart(delegate(object state)
        {
            ManualResetEvent handle = (ManualResetEvent)state;
            System.Threading.Thread.Sleep(2000);
            handle.Set();
        }));

        Thread t2 = new Thread(new ParameterizedThreadStart(delegate(object state)
        {
            ManualResetEvent handle = (ManualResetEvent)state;
            System.Threading.Thread.Sleep(4000);
            handle.Set();
        }));

        t1.Start(waitHandles[0]);
        t2.Start(waitHandles[1]);

        WaitHandle.WaitAll(waitHandles);

        Console.WriteLine("Finished");

Upvotes: 10

James L
James L

Reputation: 16864

thread1.Join();
thread2.Join();

Upvotes: 3

Related Questions