简体   繁体   中英

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:

  • The main thread has some other work to do (eg GUI).
  • The two spawned threads should be able to report exceptions and return result values

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");

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).

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

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM