Visual Studio 中的线程处理需要 Join 才能正常工作

本文关键字:常工作 工作 Join Studio 线程 处理 Visual | 更新日期: 2023-09-27 18:31:23

这更像是一个"我想知道"的问题,而不是一个真正的问题。

在努力提高我的线程技能时,我遇到了以下难题。

源代码

internal class Program
{
    private static void Main(string[] args)
    {
        var thread = new Thread(() => Print("Hello from t"));
        thread.Start();
        //thread.Join();
    }
    private static void Print(string message)
    {
        Console.WriteLine(message);
    }
}

问题所在

如果我从 Visual Studio 运行应用程序(无论是调试还是发布配置),除非我等待线程退出(使用 Join),否则message永远不会显示在"输出"窗口中。

解决方案

从命令提示符运行已编译的可执行文件,您将看到预期的输出。

我的问题

我要抛出一个疯狂的猜测,并说Visual Studio环境使一切变得不同。

我想知道的是,如果我正在开发一个实际的应用程序,我将如何使用Visual Studio来调试所述应用程序,而不会被迫修改源代码(使用Join)?

Visual Studio 中的线程处理需要 Join 才能正常工作

在实际应用程序中,由于应用在线程完成之前退出的问题,不应显示此代码。如果您确实遇到此问题,它通常表示代码存在问题。

如果使用消息泵 (WinForms) 或类似 (WPF),则应用程序将正常运行,这意味着在用户(或应用程序)通过请求应用程序退出来中断循环之前,它不会退出。在这种情况下,线程将一直工作到完成,或者直到程序退出。 无论如何,Thread.Join()可能需要调用,具体取决于方案。

如果要创建控制台应用程序,则应在程序结束时调用 Thread.Join()以确保工作线程完成。另一种方法是使用 System.Windows.Forms.Application.Run() 启动消息泵。但是,它不是为此而设计的,除非您与用户交互,否则不应使用。

另一方面,C# 中有两种线程:前台线程和后台线程。前台线程在主线程停止后继续运行。完成所有前台线程后,后台线程将停止。默认类型是前台线程。可以使用 Thread.IsBackground 属性将线程显式设置为后台。Visual Studio显然在线程中四处游荡,以至于前台线程不会阻止应用程序退出。在调试器外部运行程序工作正常。

确保所有线程在主线程之前终止仍然是一个好主意。谁知道如果在Main退出后运行更高级的代码会发生什么。

调用thread.Start()只是启动附属线程,然后返回。由于这是Main函数的结束,因此程序完成,其进程在附属线程有机会打印消息之前退出。

没有神秘感,Visual Studio环境没有什么奇怪的,只是正常的Windows进程行为。