简体   繁体   English

等待两个线程完成

[英]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. 我可以使用bgndworker和sleep spinner来检查bgnd worker的IsBusy,但我认为有更好的方法。

EDIT Some more requirements: 编辑更多要求:

  • The main thread has some other work to do (eg GUI). 主线程还有其他一些工作要做(例如GUI)。
  • The two spawned threads should be able to report exceptions and return result values 两个衍生线程应该能够报告异常并返回结果值

Quick example using Thread.Join(); 使用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: 使用等待句柄编辑另外3个示例:

            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 我喜欢这个选项 ;-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. 编辑:如果主线程是一个UI线程,你不应该阻塞其他线程完成 - 你应该(IMO)让他们在完成后回调主线程。 That way you'll still have a responsive UI while they're executing. 这样,您在执行时仍会拥有响应式用户界面。

You can't wait for finish and have GUI usable. 您不能等待完成并且可以使用GUI。 The best approach for this is to spawn threads and use events to communicate with GUI. 最好的方法是生成线程并使用事件与GUI进行通信。 Remember, that in the event handler you cannot modify control. 请记住,在事件处理程序中,您无法修改控件。 Rather that doing it directly, use Invoke method. 而是直接使用Invoke方法。

WaitHandle.WaitAny is your friend. WaitHandle.WaitAny是你的朋友。 It lets you wait on multiple threads or other kinds of objects to be signaled. 它允许您等待多个线程或其他类型的对象发出信号。

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

EDIT: 编辑:

Actually, WaitHandle.WaitAll is what you want, not WaitAny. 实际上,WaitHandle.WaitAll就是你想要的,而不是WaitAny。

http://msdn.microsoft.com/en-us/library/system.threading.waithandle.waitall.aspx 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. 一些提到的Join方法是可以的,但一个缺点是它不是完全原子操作。 This may or may not be important to you, though. 但是,这可能对您很重要,也可能不重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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