У меня проблема с QEventLoop. Я хочу создать TimeBoundExerciser для моего модульного теста, чтобы моя SUT, которая блокирует QEventLoop, не блокировала остальные тестовые случаи. В частности, мой тестовый пример - убедиться, что SUT завершает работу после тайм-аута.
TimeBoundExerciser в основном порождает поток, выполняет SUT в этом потоке, ожидает завершения потока и, если он не завершается через определенное время, вызывает метод quit () для потока через QMetaObject: : invokeMethod () и 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;
}
Метод упражнения () выполняется в главном потоке, чтобы запустить весь процесс.