如何编程以防止 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
如何防止 Node.js API REST 应用程序对高 CPU/RAM 使用率无响应?