【问题标题】:Why can't my MFC app exit completely?为什么我的 MFC 应用程序无法完全退出?
【发布时间】:2011-08-11 11:30:46
【问题描述】:

我制作了一个 MFC 应用程序,它可能有两个线程,一个用于使用 UDP 协议从套接字接收数据,一个是 MFC 应用程序的主线程。当接收到任何数据时,一些由 new 运算符在主线程中创建的对象将被通知通过应用观察者设计模式来获取数据。问题是有时我点击关闭系统按钮后,应用程序的 GUI 消失了,但在任务管理器中仍然可以找到它的进程。如果我停止数据源(UDP 客户端),这个问题将永远不会发生。下面列出了其他重要且可能有用的信息:

  1. 观察者设计模式是用 STL 容器列表实现的。我在 Attach、Detach 和 Notify 函数中使用了临界区保护。
  2. 我在关闭 UDP 套接字之前删除了观察者对象。
  3. 数据传输速率可能比进程数据快一点,因为关闭数据源后数据进程仍在工作。

我无法弄清楚我的应用无法完全退出的原因。请给我一些线索。

【问题讨论】:

  • 发布第二个线程开始的一些代码。
  • 第二个线程由socket对象创建。我从codeproject得到socket库,我觉得不会有什么错误。
  • 在调试器下运行程序。关闭主窗口。执行 Break 命令,打开 Threads 窗口,看看会发生什么。顺便说一句,从 CodeProject 下载的库可能有错误,或者您自己的代码缺少一些清理函数调用。
  • 我想我找到了问题的原因。当我按照你的方法调试我的应用程序时,我发现主线程总是阻塞在 COleDispatchDriver::ReleaseDispatch 函数中。下一行吹这个函数是Visual Studio 2008的线程窗口中的ccccccc()。我想它一定是我之前动态创建的activex对象,被删除工作线程仍在操作这些对象。所以调度操作员无法正常完成。我该如何解决?如何正确完整地动态删除一个activex控件?

标签: c++ multithreading mfc


【解决方案1】:

这通常是由您创建的线程在退出应用程序时没有以编程方式退出造成的。您的线程中必须有一个 while 子句。找到它仍在运行的地方的方法是:

  1. 使用调试模式启动你的应用,点击右上角的退出按钮退出。

  2. 从任务管理器查看它是否仍在运行

  3. 如果是,执行Debug->Break All,

  4. 打开线程窗口,双击每个线程,你会发现你的代码还在循环的地方。

【讨论】:

    【解决方案2】:

    通常一个进程不会终止,因为还有一个 foreground 线程在某处运行。当你想关闭你的应用程序时,你必须确保你的套接字库没有运行任何线程。

    【讨论】:

      【解决方案3】:

      首先,对于 MFC,请使用基于通知的方法来获取消息到达、连接等的通知。这样您就可以摆脱线程(如果有)。

      附加到调试器很容易,Break 查看哪些线程存在并等待什么。

      或者,您可以使用带有适当符号配置的 ProcessExplorer 来查看可用于特定进程的线程的调用堆栈。

      应用程序可以退出两种问题,一种可能是无限循环,另一种可能是等待/死锁(例如套接字读取命令是阻塞调用)。您可以通过附加到调试器轻松推断问题。

      否则,请提供有关线程的更多信息,可能的代码为 sn-p。

      【讨论】:

      • 谢谢。我会根据您提供的建议和信息尝试解决问题。如果我失败了,我将提供代码 sn-p。
      • 我想我已经找到了问题的原因。我发现主线程总是阻塞在 COleDispatchDriver::ReleaseDispatch 函数中。下一行吹这个函数是Visual Studio 2008的线程窗口中的ccccccc()。我想它一定是我之前动态创建的activex对象,被删除工作线程仍在操作这些对象。所以调度操作员无法正常完成。我该如何解决?如何正确完整地动态删除一个activex控件?
      • 你是对的!我应该使用消息机制来处理线程同步问题。现在一切正常。我的应用程序的性能大大提高。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-25
      • 2016-04-15
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      • 1970-01-01
      相关资源
      最近更新 更多