如何编程以防止 Windows“无响应”对话框 [重复]

Posted

技术标签:

【中文标题】如何编程以防止 Windows“无响应”对话框 [重复]【英文标题】:How to program to prevent the Windows "Not Responding" dialog [duplicate] 【发布时间】:2015-10-14 20:31:31 【问题描述】:

当应用程序未能响应 5 秒 (source) 时,Windows 会在标题栏中显示“(未响应)”,并且在某些情况下会显示“未响应”对话框:

理想情况下,5 秒以上的执行不应该阻塞主线程/事件处理线程,但是是否有一种简单的(例如 MFC C++ 的 1 班轮)方法来与 Windows 通信,主线程很忙,不应该被视为“无响应”的应用程序被关闭?使用PM_NOREMOVE 定期调用峰值PeekMessage 是最快的黑客吗?

【问题讨论】:

如果您的轮胎漏气了,您想更换它,还是在城里安装充气泵? 不要在你的 main/gui 线程中进行繁重的处理 如果你有长时间运行的操作阻塞了消息泵,最好的解决方案是有一个工作线程,让主线程继续工作而不是等待。 @Amit,是的,我同意,但假设你有一辆旧卡车,有几十个爆胎,而你每周只能买一个新轮胎。当我试图克服技术债务时,请告诉我是否有泵可以用作拐杖。 如果由于某种原因无法生成新线程,但可以将长时间运行的任务分解为更小的部分,则可以在CWinApp::OnIdle 中进行处理。只要没有 Windows 消息等待,就会从消息泵循环中调用此函数,这意味着消息以更高的优先级处理。只要您在OnIdle 中进行的处理每次调用所需的时间都相当短,这可以防止您的窗口无响应。 听起来你在按顺序做某事,你只是希望用户能够在那几秒钟内移动窗口。您可能已准备好处理取消/关闭,而其他控件被禁用。所以在这种情况下PeekMessage 很好。您可以使用while(PeekMessage(... PM_NOREMOVE)) AfxGetThread()->PumpMessage(); 这不是作弊或黑客攻击。 【参考方案1】:

真的没有什么技巧可以解决这个问题。任何对消息泵的胡思乱想都可能导致各种灾难,尤其是在 COM 和其他系统消息处理方面。

不要拖住主线程。

将运行时间较长的任务移至后台或工作线程,并轮询未来是否完成,或者让线程将消息发回 GUI 以表明它已完成,然后检索所需的结果。

【讨论】:

【参考方案2】:

在很久以前的 Windows 3.1 世界中,答案是将您的工作分成短期块,在窗口的消息过程中运行这些块,然后通过调用 PostMessage 从一个块转到另一个块。

现在您更新窗口以显示工作正在进行中,生成一个线程并在线程结束时调用一些 PostMessage 等效项,以便您的窗口可以自行更新并显示结果。

【讨论】:

【参考方案3】:

不,没有快速破解,因为如果您使用这样的主线程,您的应用确实没有响应。

【讨论】:

以上是关于如何编程以防止 Windows“无响应”对话框 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

繁忙的应用程序导致 Windows 7 上出现错误的“无响应”状态 - WM_UPDATE

如何以编程方式更改我的 Windows 桌面墙纸?

如何防止 Node.js API REST 应用程序对高 CPU/RAM 使用率无响应?

如何以编程方式清除 WinInet SSL 状态(是不是有 Windows API 调用)?

Android 应用程序无响应

以编程方式创建并添加到 uiimageview 时,UIButton 无响应