如何退出所有正在运行的线程?

时间:2010-04-22 07:24:40

标签: c# .net winforms multithreading

以下代码不会退出应用程序。如何退出应用程序并确保所有正在运行的线程都已关闭?

foreach (Form form in Application.OpenForms)
{
    form.Close();
}
Application.Exit();

7 个答案:

答案 0 :(得分:82)

您没有在代码中显示任何线程的使用,但我们假设您确实有线程。要关闭所有线程,您应该在启动它们之前将它们全部设置为后台线程,然后在应用程序退出时自动关闭它们,例如:

Thread myThread = new Thread(...);
myThread.IsBackground = true; // <-- Set your thread to background
myThread.Start(...);

来自microsoft的“HOWTO:Stop Multiple Threads”文章:http://msdn.microsoft.com/en-us/library/aa457093.aspx

答案 1 :(得分:50)

您可以尝试以下代码:

Environment.Exit(Environment.ExitCode);

答案 2 :(得分:23)

我在我的软件中遇到了类似的问题,但不幸的是,只是让线程在后台运行并没有解决问题。事实上,当线程带回数据(主要软件是数据驱动的),如果我关闭应用程序,它会导致Windows错误,从而产生调试信息。

那么实际上对我有用的是什么:

第1步:让所有线程在后台运行,例如

Thread aThread = new Thread(MethodName);
aThread.IsBackground = true; //<-- Set the thread to work in background
aThread.Start();

第2步:在表单/应用程序的结束操作中调用Environment.Exit方法,例如

Environment.Exit(Environment.ExitCode);

这样可以很好地管理内存,没有内存泄漏。

希望这有帮助。

答案 3 :(得分:13)

这适用于您打开的所有主题。

protected override void OnExiting(Object sender, EventArgs args)
{
    base.OnExiting(sender, args);
    Environment.Exit(Environment.ExitCode);
}

答案 4 :(得分:3)

这让我完成了工作:

而不是使用:

Application.Exit() 

打开其他线程,尝试使用:

Environment.Exit(Environment.ExitCode);

答案 5 :(得分:2)

这是确保应用程序(强制关闭)的最佳方法:

(Process.GetCurrentProcess()).Kill()

Environment.Exit的问题在于,除非它在主线程上,否则它不起作用。另外,有时它会线程锁定。

您的程序无法正确关闭的主要原因是因为表单无法处理自身(因此无法处理其创建的所有对象)。解决这个问题要困难得多。我建议在等待任何可能的处理程序首先被调用之后再运行上面的代码。

答案 6 :(得分:-2)

我对此感到困惑了一段时间,因为常见的答案是让您调用的线程mythread.IsBackground = true;

运行线程的常见答案是使用带有标志的 while 循环

while(!exitflag)
{
    // thread running
}

当用户按下退出表单按钮时,Visual Studio 仍在运行线程,但表单已关闭。我使用 Form Closing 事件来设置 exitcode 标志,然后等待线程关闭。

我有一个使用 Timer 和两个附加线程的单一表单,一个收集流数据,另一个对该数据进行计算并保存到 sql 表。数据收集在循环缓冲区中收集。我使用两个静态 bool 值作为标志,其中线程使用 mythread.Isalive 将标志设置为 true 或 false,因为表单关闭事件无法访问线程句柄。

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    Debug.WriteLine("Form Closing Event");
    exitFlag = true;
    int ThreadsClosed = 0;
    while (ThreadsClosed < 2)
    {
        ThreadsClosed = 2;
        if (ProcessDataAlive) ThreadsClosed = 0;
        if (StreamingDataAlive) ThreadsClosed = 0;
        Application.DoEvents();
    }
    Debug.WriteLine("Threads are all closed");
    Thread.Sleep(5000); // allow debug window open to read remove for release
}