这更像是一个“我想知道”的问题,而不是一个真正的问题。
在努力提高我的线程技能的同时,我遇到了以下难题。
源代码
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
)?
答案 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
退出后运行更高级的代码,可能会发生什么。