[英]Foreground thread don't stop a console process from terminating?
在以下WPF代码中,单击按钮后,将启动新的前台线程。 然后关闭WPF窗口,可以看到在Windows任务管理器中,直到Thread.Sleep(100000)
结束,该过程才会终止。 我能理解它,因为如MSDN doc所述,前台线程可能会阻止进程终止。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
new Thread(Go).Start();
}
private void Go(object obj)
{
Thread.Sleep(100000);
}
}
但是,当我在控制台程序中尝试几乎相同的操作时,关闭控制台窗口后,该过程立即终止。 任何人都可以帮助解释差异吗?
class Program
{
static void Main(string[] args)
{
new Thread(Go).Start();
}
private static void Go()
{
Thread.Sleep(100000);
}
}
但是,当我在控制台程序中尝试几乎相同的操作时,关闭控制台窗口后,该过程立即终止。 任何人都可以帮助解释差异吗?
TL; DR; 不同之处在于它是一个控制台应用程序,并且您单击关闭框 。 这与从“ 任务管理器”中删除它非常相似。 此外, 所有控制台应用程序主线程也是前台线程 。 请参阅此答案末尾的示例。
如果单击控制台应用程序上的关闭框,则Windows将杀死所有线程并关闭控制台应用程序,而不管线程是后台线程还是前台线程。 对于GUI应用程序,例如WinForms或WPF; 规则“一旦属于某个进程的所有前台线程都终止,则公共语言运行库将终止该进程” 。 与控制台应用程序不同,在GUI应用程序上单击关闭框和进程终止之间没有直接链接。
如果在调试器中运行以下代码,它将等待另一个线程完成。 但是, 单击关闭框会使该过程无效,并且控件返回到 Visual Studio,从而证明该过程确实已经退出并且没有像Windows Forms可以使用前台线程那样进行捉迷藏。 (关闭仍在运行中的前台线程的WinForms主应用程序窗口只会关闭该窗口,而不必关闭进程)
namespace ConsoleApplication10
{
class Program
{
static void Main(string[] args)
{
new Thread(Go).Start();
Console.WriteLine("Main thread {0} exiting", Environment.CurrentManagedThreadId);
}
private static void Go()
{
var thread = Thread.CurrentThread;
Console.WriteLine("{0} thread {1} sleeping",thread.IsBackground ? "Background" : "Foreground", thread.ManagedThreadId);
Thread.Sleep(100000);
}
}
}
假设您没有单击关闭框,那么直到所有线程完成后,控制台应用程序才会终止。
MSDN:
一旦属于某个进程的所有前台线程都终止,公共语言运行库将终止该进程
您可以通过以下简单方式证明此控制台应用程序的行为:
static void Main(string[] args)
{
var thread = Thread.CurrentThread;
Console.WriteLine("{0} thread {1} sleeping", thread.IsBackground ? "Background" : "Foreground", thread.ManagedThreadId);
Thread.Sleep(100000);
}
现在我们没有在此处生成任何新线程,但是只需单击关闭框就足以将进程发送给遗忘对象。 但是,等等,您是否看到主线程实际上是前台线程 ?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.