【问题标题】:Application process does not exit after main form is closed - using ApplicationContext主窗体关闭后应用程序进程不退出 - 使用 ApplicationContext
【发布时间】:2014-01-22 10:58:10
【问题描述】:

我有一个 windows 窗体应用程序,关闭主窗体后进程不退出。

我使用 ApplicationContext,因为我有一个演示者来生成我的主表单。

Application.Run(new ApplicationContext(Instance.InitPresentationManager()));

出于调试目的,我重写了 DestroyHandle 和 OnHandleDestroyed 方法。 在那里我可以看到 DestroyHandle 被调用但 OnHandleDestroyed 没有! 这就是我的进程仍在运行的原因,因为 ApplicationContext 在内部注册到 HandleDestroyed 事件。

在 DestroyHandle 方法中,属性 HandleCreated 甚至从 true 变为 false。 我什至重写了 WndProc 并且可以看到没有收到消息“2”(这个在 Control 类中调用 WmDestroy 并触发 OnHandleDestroyed 事件)。

这怎么可能?

备注:

  • OnHandleDestroy 仅在 RecreatingHandle 为 true 时才在开始时调用
  • 附加到进程并中断所有线程时,主线程仍在Application.Run方法中
  • 我什至附上了一个内存分析器,它告诉我不再有我的主窗体的实时实例
  • 主窗体的 Dispose 中的 Application.Exit 工作并处理症状,但不处理问题本身
  • 电脑重启后一段时间正常工作,但最终问题再次出现
  • Win 7 64 位,VS 2010,.net 4.0

【问题讨论】:

    标签: c# winforms process exit applicationcontext


    【解决方案1】:

    问题是表单关闭并不一定意味着应用程序应该终止它当前正在执行的操作。 (想想写日志文件,整齐地关闭通信流等)。

    线程有一个属性IsBackground(参见http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground(v=vs.110).aspx),它有效地表示它是否被允许在运行中被杀死。检查任何正在进行的线程以确保它们正在使用适当的后台线程标记运行。

    在应用程序上下文中尝试 dispose 方法。这是一个完全可以接受的模式和方式,表示我已经完成了这个,去摆脱它,让长时间运行的线程完成。

    【讨论】:

    • 通过使用 Application.Run 这必然意味着当窗体关闭时应用程序必须退出,请参阅 MSDN:msdn.microsoft.com/en-us/library/ms157902%28v=vs.100%29.aspx
    • 终止!=退出。终止是“停止你现在正在做的事情”。退出是“完成后完成”
    • 这就是我在问题中提到的内容。主线程仍在运行。因此应用程序不会退出。更糟糕的是,MSDN 文档中似乎存在错误,他们声明 Application.Run 正在等待表单关闭事件。我检查了他们正在等待处理被破坏事件的源 - 在我的情况下没有触发。
    • 您的主窗体中正在进行什么处理?你开始任何线程吗?你能提供一个简单的源代码示例吗?
    • 主要形式或多或少是愚蠢的。只是 GUI 的东西和在按钮上注册事件处理程序等等。这就是整个 Presenter 实现的原因,让业务逻辑远离 GUI 控件和表单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多