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

时间:2022-11-24 09:17:54

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.

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

Why I'm posting this question

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.

令我遗憾的是,有一个流行的收缩包装应用程序,每次遇到模态对话框中的异常错误时都会挂起。当我们从整数错误代码大量转换到异常时,我负责选择std :: exception作为抛出异常的基类。直到大量工作进入转换,我们的测试才发现了这个问题,到那时为时已经太晚了。希望这个问题/答案会让某人犯同样的错误。

3 个解决方案

#1


8  

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.

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

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

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

#2


3  

If you are interested in learning about how Windows detects apphangs we have added some posts to this on the Windows Error Reporting blog:

如果您有兴趣了解Windows如何检测apphangs,我们在Windows错误报告博客上添加了一些帖子:

Let there be hangs part 1 of 4

让我们挂起第4部分

Let there be hangs part 2 of 4

让我们挂起4的第2部分

Let there be hangs part 3 of 4

让我们挂起4的第3部分

Let there be hangs part 4 of 4

让我们挂起4的第4部分

Important to note is that this information when sent through Microsoft's Windows Error Reporting gets communicated to the software developers to try and fix these issues. If you are sending in your error reports you WILL help fix issues that are occuring on your PC!

需要注意的是,通过Microsoft的Windows错误报告发送的此信息会传达给软件开发人员,以尝试解决这些问题。如果您要发送错误报告,您将有助于解决PC上出现的问题!

I am a Program Manager at Microsoft on the Windows Error Reporting team.

我是Windows错误报告团队的Microsoft项目经理。

#3


1  

Mark's answer is correct. For a much more rigorous analysis of this problem and a detailed suggestion for dealing with it in your own code, see this FAQ by Doug Harrison (section Q6 in particular).

马克的答案是对的。有关此问题的更严格分析以及在您自己的代码中处理此问题的详细建议,请参阅Doug Harrison的此常见问题解答(特别是第6节)。

#1


8  

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.

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

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

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

#2


3  

If you are interested in learning about how Windows detects apphangs we have added some posts to this on the Windows Error Reporting blog:

如果您有兴趣了解Windows如何检测apphangs,我们在Windows错误报告博客上添加了一些帖子:

Let there be hangs part 1 of 4

让我们挂起第4部分

Let there be hangs part 2 of 4

让我们挂起4的第2部分

Let there be hangs part 3 of 4

让我们挂起4的第3部分

Let there be hangs part 4 of 4

让我们挂起4的第4部分

Important to note is that this information when sent through Microsoft's Windows Error Reporting gets communicated to the software developers to try and fix these issues. If you are sending in your error reports you WILL help fix issues that are occuring on your PC!

需要注意的是,通过Microsoft的Windows错误报告发送的此信息会传达给软件开发人员,以尝试解决这些问题。如果您要发送错误报告,您将有助于解决PC上出现的问题!

I am a Program Manager at Microsoft on the Windows Error Reporting team.

我是Windows错误报告团队的Microsoft项目经理。

#3


1  

Mark's answer is correct. For a much more rigorous analysis of this problem and a detailed suggestion for dealing with it in your own code, see this FAQ by Doug Harrison (section Q6 in particular).

马克的答案是对的。有关此问题的更严格分析以及在您自己的代码中处理此问题的详细建议,请参阅Doug Harrison的此常见问题解答(特别是第6节)。