【问题标题】:Why the Main thread waits other threads without using join() [duplicate]为什么主线程等待其他线程而不使用 join() [重复]
【发布时间】:2022-01-06 23:12:27
【问题描述】:

对不起,如果我的问题看起来很幼稚。我是 C# 和 .Net 的新手,但我仍然对它们感兴趣。 我来自 Go-Lang 背景,并尝试学习 C#/.Net 多线程。

在 Go 中,如果不使用等待,主线程将运行并完成其逻辑而不管其他线程。 我认为它在 C# 中应该是相同的,但是,下面的代码允许所有线程完全运行。 这意味着主线程等待其他线程完成,而不使用 join() 或任何其他等待技术。 请让我知道我在这里遗漏了什么或误解了什么。

namespace TestThread
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Thread T1 = new Thread(PrintY);
            T1.Start();
   

            // The following is the funtion of the Main thread.
            for (int i = 0; i < 10; i++) Console.Write("x");

        }

        static void PrintY()
        {
            for (int i = 0; i < 100; i++)
            {
                Console.Write("Y");
                Thread.Sleep(100);
            }
        }


    }
}

输出如下:

xxxxxxxxxYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

Main 方法完成之前,我预计结果中最多有一个Y,因此进程终止。当主线程完成时,是什么让进程保持活动状态?

【问题讨论】:

  • 创建一个线程需要时间,而此时主程序逻辑会执行。
  • @500-InternalServerError 我认为 OP 是在问为什么要打印任何 Y,他们希望主线程很快终止并停止 T1 线程。
  • @DavidG:是的,我现在明白了——下面还有一个答案。

标签: c# .net multithreading


【解决方案1】:

当您通过构造函数创建Thread 时,默认情况下它的Thread.IsBackground 设置为false

线程要么是后台线程,要么是前台线程。后台线程与前台线程相同,只是后台线程不会阻止进程终止。一旦属于一个进程的所有前台线程都已终止,公共语言运行时就会结束该进程。任何剩余的后台线程都将停止并且不会完成。

还有:

默认情况下,以下线程在前台执行(即它们的IsBackground属性返回false):

  • 主线程(或主应用程序线程)。
  • 通过调用 Thread 类构造函数创建的所有线程。

所以它会阻止应用程序终止。如果您希望您的线程允许应用程序终止,您可以将此属性设置为false

Thread T1 = new Thread(PrintY);
T1.IsBackground = true;
...

另请注意,在现代 C# 中很少需要手动创建线程。引入Task Parallel Library (TPL)后,通常使用Task API,而不是直接操作线程(例如_ = Task.Run(PrintY);可以在这种情况下使用)。

【讨论】:

  • @helhadad 我不熟悉 go,但我会说(正如我在答案中所写) - 你最好考虑使用 Tasks 而不是 Threads。
  • 我想知道在前台线程中使用 join() 是否有意义。
  • @helhadad 这取决于。如果你想暂停当前方法的执行直到线程完成 - 那么是的。但同样 - 通常最好使用 Tasks(和 async-await 用于类似目的)。
猜你喜欢
  • 2020-09-21
  • 1970-01-01
  • 2017-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多