我在使用QEventLoop时遇到问题。我想为单元测试创建一个“TimeBoundExerciser”,以使在QEventLoop上阻塞的SUT不会阻塞其余的测试用例。具体来说,我的测试用例是确保SUT在超时后终止。
TimeBoundExerciser基本上产生一个线程,在该线程上执行SUT,等待该线程终止,如果在特定时间后仍未终止,则通过QMetaObject::invokeMethod()对该线程调用quit()方法。 )和QueuedConnection。我希望执行quit()将导致嵌套的QEventLoop退出,从而终止我的线程。但是,我发现,永远不会调用quit()方法,并且线程永远不会终止。我的TimeBoundExerciser的代码如下:
class IExerciseTheSystem
{
void operator()() = 0;
};
class TimeBoundExerciser : private QThread
{
Q_OBJECT
public:
enum CompletionType
{
TERMINATED,
FORCE_QUIT,
QUIT
};
TimeBoundExerciser(const IExerciseTheSystem& exerciser);
CompletionType exercise(unsigned long timeoutMillis);
protected:
void run();
protected slots:
void exerciseTheSystem();
private:
const IExerciseTheSystem& exerciser;
};
TimeBoundExerciser::TimeBoundExerciser(const IExerciseTheSystem& exerciser) : exerciser(exerciser)
{
}
TimeBoundExerciser::CompletionType TimeBoundExerciser::exercise(unsigned long timeoutMillis)
{
start();
while (!isRunning())
{
msleep(10);
}
moveToThread(this);
wait(timeoutMillis);
if (!isFinished())
{
bool quitResult;
QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection, Q_RETURN_ARG(bool, quitResult));
wait();
return FORCE_QUIT;
}
return QUIT;
}
void TimeBoundExerciser::run()
{
setTerminationEnabled(true);
QMetaObject::invokeMethod(this, "exerciseTheSystem", Qt::QueuedConnection);
exec();
}
void TimeBoundExerciser::exerciseTheSystem()
{
cout << "Starting exerciser" << endl;
exerciser();
cout << "Exerciser ended" << endl;
}
exercise()方法在主线程上执行,以启动整个过程。
最佳答案
如果测试运行时间过长,则可能是某种形式的循环处理数据。
自然,由于测试线程正忙于运行测试,因此不会发出您的退出请求。消息不会中断线程,当线程完成对上一条消息的处理并恢复事件循环时,将对其进行处理。
关于c++ - 为什么我的嵌套QEventLoop无法为QThread传递所有事件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3627714/