【问题标题】:How would I wait for multiple threads to stop?我将如何等待多个线程停止?
【发布时间】:2025-12-19 06:10:11
【问题描述】:

我有一个产生大约 20 个工作线程的主线程。
我需要停止主线程,直到所有其他线程都完成。
我知道(线程)。加入。但这仅适用于一个线程。

多个连接会像这样损害性能。

t1.Join()
t2.Join()
...
t20.Join()

因为程序一个接一个地等待每个停止。

我将如何做到这一点 主线程等待所有一组线程结束?

【问题讨论】:

  • 这是理想的行为,对吧?它首先等待 t1 并不重要(虽然 t3 可能已经完成),最后,当 callstackpointer 越过 t20.Join; 你知道所有线程都已停止。
  • 像糖果一样对待线程是一个常见的错误。仅当您的机器具有至少 20 个 CPU 内核时才启动 20 个线程。开始更多实际上会减慢您的程序。为这么多线程获得正确的锁定也非常困难,您通常只是让线程相互等待。
  • 基本上,我必须将 20 个不同的文件加载到我的程序中。线程不必交互。无论计算机有多少内核,我都希望它能够正常工作。另外,我需要主程序等到所有 20 个文件都打开。
  • 其实,如果都是 IO-bound 的话,启动 20 个线程也不一定是异常的。

标签: c# multithreading c#-4.0


【解决方案1】:

你真的应该看看Task Parallelism (Task Parallel Library)。它使用线程池,但也管理任务窃取等。

引用:“TPL 动态调整并发程度,以最有效地使用所有可用的处理器。此外,TPL 处理工作的分区、线程池上的线程调度、取消支持、状态管理和其他低级细节。" on Task Parallel Library

你可以这样使用它:

Task[] tasks = new Task[3]
{
    Task.Factory.StartNew(() => MethodA()),
    Task.Factory.StartNew(() => MethodB()),
    Task.Factory.StartNew(() => MethodC())
};

//Block until all tasks complete.
Task.WaitAll(tasks);

或者,如果您使用某种循环来生成线程:

Data Parallelism (Task Parallel Library)

【讨论】:

【解决方案2】:

joins 可以满足您的要求。主线程仍然必须等待所有工作线程终止。查看此网站,这是来自C# in a Nutshell 的示例章节。恰好是线程章节:http://www.albahari.com/threading/part4.aspx

【讨论】:

    【解决方案3】:

    我看不出等待线程一个接一个完成会导致明显的性能损失。因此,一个简单的 foreach 可以满足您的需求,而无需任何不必要的花里胡哨:

    foreach (Thread t in threads) t.Join();
    

    注意:当然,有一个 Win32 API 函数允许同时等待多个对象(在本例中为线程)——WaitForMultipleObjectsEx。 Internet 上有许多帮助程序类或线程框架,它们可以根据需要使用它。但是对于一个简单的案例,您真的需要它们吗?

    【讨论】:

      【解决方案4】:

      多个连接会损害性能 像这样。

      没有“性能损失”,如果您想等待所有线程退出,请在线程上调用 .join()。

      把你的话题塞进一个列表然后做

      foreach(var t in myThread)
           t.join();
      

      【讨论】:

        【解决方案5】:

        如果您确定您将始终拥有

        在本机代码中,您可以在线程句柄上执行相同的操作,但不确定如何在 .Net 中执行此操作。

        另请参阅之前的问题:C#: Waiting for all threads to complete

        【讨论】: