wxWidgets-单线程多任务处理



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

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

在这3秒钟的时间里,我的应用程序基本上会被冻结,直到显示wxMessageBox为止。有没有一种方法可以在后台运行而不使用多个线程?它给我开发的应用程序带来了问题。

我想知道是否有一些类型的事件处理可以使用。任何形式的帮助都将不胜感激。

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

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

  2. 只要没有其他事件要处理,就使用EVT_IDLE事件来执行任务。这对于小任务来说还不错,因为你需要能够在处理程序中恢复处理,所以小任务可以分解成足够小的部分。不要忘记调用event.RequestMore()以继续获取空闲事件,即使没有其他情况发生。

  3. 最糟糕和最危险的是按照另一个答案的建议呼叫wxYield()。这在最初看起来很简单,但您稍后会后悔这样做,因为这可能会在代码中产生极其难以调试的可重入性问题。如果你确实使用了它,你需要自己防止到处都有可重入性,你应该真正了解这个函数的作用。

试试这个:

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

我知道游戏已经晚了,但是。。。

我已经成功地使用EVT_IDLE方法多年了(最初是在90年代使用Motif)。主要的想法是把你的任务分解成小块,每一块调用下一块(想想链表)。这样做的机制是使用CallAfter()方法(当然使用C++)。您只需将"CallAfter()"作为文章的最后一步,这将允许GUI主循环运行另一次迭代,并可能在调用下一篇文章之前更新GUI元素等。只要记得把碎片保持小。

使用后台线程真的很好,但可能比你想象的更棘手。。。最后只要你知道你在后台处理的数据不会被其他任何东西触摸/查看,你就没事。如果你知道是这样,那就是办法。此方法允许GUI在后台计算(调整窗口大小/移动窗口等)期间保持完全响应

在任何一种情况下,第一步都不要忘记对适当的GUI元素进行脱敏处理,这样就不会意外地多次启动同一个后台任务(例如,意外地连续多次单击启动后台线程的按钮)。

最新更新