У меня проблема с QEventLoop. Я хочу создать «TimeBoundExerciser» для моего модульного теста, чтобы мой SUT, который блокирует QEventLoop, не будет блокировать остальные тестовые примеры. В частности, мой тестовый пример - убедиться, что SUT завершает работу после таймаута.Почему мой вложенный QEventLoop не передает все события для моего QThread?
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;
}
упражнения() выполняется в главном потоке, чтобы начать весь процесс.
Вы когда-нибудь видели выход из exerciseTheSystem()? –
Я вижу «Запуск тренажера», но не «Тренажер закончился». – gregsymons
Что происходит в тренажере()? Это когда-нибудь заканчивается? –