当我抛出异常时,为什么我的 MFC 应用程序会挂起?

2022-01-12 00:00:00 windows c++ mfc

如果您从 MFC 对话框中引发异常,应用程序将挂起,即使您的代码中有一个 catch 块.它拒绝响应鼠标或键盘,关闭它的唯一方法是使用任务管理器.

If you throw an exception from inside an MFC dialog, the app hangs, even if you have a catch block in your code. It refuses to respond to the mouse or keyboard, and the only way to shut it down is to use Task Manager.

让我感到羞耻的是,有一个流行的收缩包装应用程序每次在模式对话框中遇到异常错误时都会挂起.当我们从整数错误代码大规模转变为异常时,我负责选择 std::exception 作为抛出异常的基类.直到大量的工作投入到转换中,我们的测试才发现了这个问题,到那时改变已经太迟了.希望这个问题/答案能防止人们犯同样的错误.

To my shame, there is a popular shrink-wrapped application that hangs every time it encounters an exceptional error in a modal dialog. When we made a massive shift from integer error codes to exceptions, I was responsible for choosing std::exception as the base class for the thrown exceptions. It wasn't until a huge amount of work went into the conversion that our testing uncovered this problem, and by then it was too late to change. Hopefully this question/answer will keep someone from making the same mistake.

推荐答案

CDialog::DoModal 的代码通过禁用父窗口使对话框模式化.当对话框代码返回时,窗口将重新启用.对于 CException* 错误有一个明确的捕获,但对于任何其他类型的抛出异常都没有;因此父窗口永远不会重新启用.

The code for CDialog::DoModal makes the dialog modal by disabling the parent window. When the dialog code returns, the window is reenabled. There is an explicit catch for CException* errors, but not for any other kind of thrown exception; thus the parent window never gets reenabled.

更改您的代码以抛出指向从 CException 派生的任何异常的指针,您将解决问题.

Change your code to throw a pointer to any exception derived from CException, and you'll fix the problem.

相关文章