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

时间:2012-04-16 20:41:07

标签: c# multithreading visual-studio

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

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

源代码

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运行应用程序(无论是Debug还是Release配置),message永远不会显示在输出窗口中,除非我等待线程退出(使用Join)。

解决方案

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

我的问题

我会猜测并说Visual Studio环境会有所不同。

我想知道的是,如果我正在开发一个真实世界的应用程序,我将如何使用Visual Studio调试所述应用程序,而不必强制修改源代码(使用Join)?

2 个答案:

答案 0 :(得分:2)

调用thread.Start()只是启动辅助线程然后返回。由于这是Main函数的结束,程序结束并且其进程在子线程有机会打印消息之前退出。

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

答案 1 :(得分:2)

在实际应用程序中,由于在线程完成之前应用程序退出的问题,不应出现此代码。如果确实遇到此问题,通常会发出代码问题。

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

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

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

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