我的应用程序是一个执行某些复杂数学算法的窗口应用程序。因为很久以前就开始做应用,大部分还是单线程的。更准确地说,主线程执行所有复杂的计算逻辑。值得一提的是,在计算过程中,我在屏幕上显示了一些进度。
在大多数情况下,数学算法只需要几秒钟,因此在用户开始操作后,会显示一个沙漏(或 Windows 7 中的运行圈),几秒钟后显示结果。
在某些情况下,该算法可能需要几分钟时间。在此期间,我显示沙漏,算法忙时,我在窗口中显示进度。但是,如果用户在应用程序忙碌了一段时间后点击它,窗口就会变得“更白”(就像在窗口上铺了一 block 不完全透明的塑料片),窗口就不会再更新了,并且 Windows 报告“应用程序没有响应”。
我使用 Qt 并使用 Qt 函数 QWidget::repaint 在我的算法繁忙时强制重绘。重绘工作了一段时间,但如上所述,Windows 似乎在一段时间后阻止了它。
告诉 Windows 您的应用程序仍然很忙以便窗口继续更新的正确方法是什么?如果我进入一个明确的消息循环,用户可能会在应用程序中触发我不想要的其他操作。
- 是否足以调用 PeekMessage?
- 调用 GetMessage 就足够了吗?
- 或者我应该调用 DispatchMessage 吗?以及如何阻止用户开始另一个操作(实际上,阻止所有用户输入)
- 我应该在每次更新我的窗口时调用这些消息之一,还是我可以限制自己每隔几秒调用一次(10 秒?、30 秒?...)
请注意,将计算逻辑移动到单独的线程目前不是一种选择。
我在 Windows 7 上结合使用 Visual Studio 2010 和 Qt 4.7。
最佳答案
您应该将 GUI 与应用程序逻辑分开。所有其他解决方案都是黑客。使用 Qt
可以很容易地将计算逻辑移动到一个单独的线程中,只需付出很少的努力。
我假设有一个函数(我们称它为 execute()
),当调用它时执行所有这些耗时的数学运算。一种选择是使用 Qt Concurrent API用于在单独的线程中调用此函数,而不使用低级线程处理。
您需要的是 QtConcurrent::run
功能:
The QtConcurrent::run() function runs a function in a separate thread. The return value of the function is made available through the QFuture API.
不是简单地调用 execute()
这将阻止您的用户界面,您可以执行以下操作(让 A
成为 execute()
已定义):
QFuture<void> future = QtConcurrent::run(this, &A::execute);
您可以使用 QFutrureWatcher
为了得到有关功能何时完成的通知。
关于windows - 如何让 Windows 认为您的应用程序仍然很忙,尽管它没有响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8412188/