【问题标题】:Closing main app while form is running a thread在表单运行线程时关闭主应用程序
【发布时间】:2014-09-01 06:15:49
【问题描述】:

我有一个 C# windows 应用程序,我在其中创建了某个类的实例,其中它有一个成员,它是一个窗口窗体,并且这个窗体有一个按钮,当我单击它时,我会打开一个可以运行的新窗体一个工作线程,比方说:

public static void Main()
{
    MyClass mc = new MyClass();
    mc.ShowForm();
}

在 MyClass.cs 中:

public void ShowForm()
{
    MyFirstForm firstForm = new MyFirstForm();
    firstForm.Show();
}

在 MyFirstForm.cs 中:

private void myButton_Click(object sender, EventArgs e)
{
    MySecondForm secondForm =  new MySecondForm();
    secondForm.Show();
}

在 MySecondForm.cs 中:

private void startButton_Click(object sender, EventArgs e)
{
    var worker = new Thread(StartWork);
    worker.Start();
}

private void stopButton_Click(object sender, EventArgs e)
{
    m_stopped = true;
}

private void StartWork()
{
    while(!m_stopped)
    {
       //work...
    }
}

当我运行我的应用程序时,单击 myButton,然后单击 startButton,然后退出我的应用程序(我有一个托盘图标,当单击退出时,调用 base.Shutdown() ),第二个表单保持挂起且无响应。

我最初的问题是,通知第二个表单它应该关闭并停止正在运行的线程的最佳方法是什么,但是在写这篇文章时我注意到我可以使用Task.Factory.StartNew(StartWork);,当我尝试它时,它起作用了顺利。 所以现在我有另一个问题,为什么会这样?

我尝试注册到ClosingClosedFormClosing 事件并设置m_stopped = true,但没有被调用。

编辑: 正如@drf 建议的那样,该线程是前台线程,因此应用程序在运行时被阻塞,因此添加:

worker.IsBackground = true;

修复它。

【问题讨论】:

  • 设置其父表单 - .Show(this),所有子表单都应与其父表单关闭
  • 您可以跟踪Form Closing事件并关闭正在运行的线程。
  • 将线程上的IsBackground 属性设置为真正的工作吗?
  • @drf - 是的,确实有效。不明白为什么Closing没有被触发?
  • @ShaZiv,您能说明您是如何注册FormClosing 活动的吗?

标签: c# multithreading forms user-interface task


【解决方案1】:

您的线程当前是一个前台线程,它将阻止进程退出,直到线程完成。 http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground(v=vs.110).aspx

把你的线程启动代码改成这样:

private void startButton_Click(object sender, EventArgs e)
{
    var worker = new Thread(StartWork);
    worker.IsBackground = true;
    worker.Start();
}

【讨论】:

  • 太好了。你试过了吗?如果是这样,请您更新帖子中的代码以显示它吗?否则,经常使用 .net 线程的人会立即得出与我相同的结论。
【解决方案2】:

我认为关闭应用程序你应该使用Application.Exit Method:

它通知所有消息泵它们必须终止,然后在处理完消息后关闭所有应用程序窗口。

您还可以跟踪每个表单的FormClosing 事件。检查Thread.IsAlive然后Thread.Abort()或取消关闭。

【讨论】:

  • 不,绝对不是,Application.Exit 错过了重要的关闭步骤。
  • @Sayse。您的意思是关闭个别表格?
  • 这与我在帖子中提到的链接相同。你能检查一下备注部分吗?
  • Closed 和 Closing 事件是过时的方法。哪些是不同的。
猜你喜欢
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 2017-03-13
  • 1970-01-01
  • 1970-01-01
  • 2016-10-08
  • 2015-04-22
  • 2017-01-06
相关资源
最近更新 更多