wxWidgets - 使用单线程进行多任务处理

时间:2012-12-17 23:41:06

标签: c++ multithreading background wxwidgets multitasking

我有一个用wxWidgets创建的GUI应用程序。作为功​​能的一部分,我必须在操作GUI窗口的同时运行“任务”。例如,我可以运行代码:

long currentTime = wxGetLocalTime();
long stopTime = wxGetLocalTime() + 3;
while (wxGetLocalTime() != stopTime) {}
wxMessageBox("DONE IN APP");

在这3秒的持续时间内,我的应用程序基本上会被冻结,直到显示wxMessageBox。有没有办法让这个在后台运行而不使用多个线程?它为我正在开发的应用程序带来了问题。

我想知道是否有某些类型的事件处理可以使用。非常感谢任何形式的帮助。

3 个答案:

答案 0 :(得分:5)

在GUI wx应用程序中运行耗时的任务有三种方法:

  1. 到目前为止,最优选的是使用不同的线程。应用程序的解释“非常严重的GUI”对我来说真的没有任何意义,我认为如果它的GUI强度(无论它是什么)阻止你使用后台工作线程,你应该认真重新考虑你的程序设计。如果你使用这种方法,它很简单,但要特别注意线程/程序终止问题。特别是,您需要等待线程完成(如果不需要很长时间才能运行),或者在退出程序之前明确取消它。

  2. 只要没有其他要处理的事件,就可以使用EVT_IDLE事件来执行任务。这对于小型任务来说并不算太糟糕,因为您需要能够在处理程序中恢复处理。即使没有发生任何事情,也不要忘记致电event.RequestMore()继续获得闲置事件。

  3. 最糟糕和最危险的是按照另一个答案的建议拨打wxYield()。这最初看起来很简单,但是你后悔这样做会因为这会在代码中调试极其难以调试的重入问题。如果你确实使用它,你需要在任何地方防止重入,你应该真正理解这个函数究竟是做什么的。

答案 1 :(得分:3)

试试这个:

long currentTime = wxGetLocalTime();
long stopTime = wxGetLocalTime() + 3;
while (wxGetLocalTime() != stopTime) {
   wxYield();
}
wxMessageBox("DONE IN APP");

答案 2 :(得分:2)

我知道这场比赛已经晚了,但是......

我已成功使用EVT_IDLE方法获取YEARS(最初是在90年代使用Motif)。主要思想是将你的任务分解成小块,每一块都调用下一块(想想链接列表)。执行此操作的机制是使用CallAfter()方法(当然使用C ++)。您只需将“CallAfter()”作为该片中的最后一步,这将允许GUI主循环运行另一次迭代,并可能在调用下一篇文章之前更新GUI元素等。请记住保持小件。

使用后台线程非常好,但可能比你想象的更棘手......最终。只要您知道您在后台处理的数据不会被其他任何内容触及/查看,您就可以了。如果您知道这种情况,那么这就是要走的路。此方法允许GUI在后台计算期间保持完全响应(调整大小/移动窗口等)

在任何一种情况下,只要不要忘记将适当的GUI元素作为第一步去敏感,这样您就不会意外地多次启动相同的后台任务(例如,偶然多次连续点击一个按钮,启动后台线程)。

相关问题