Несколько задержанных вызовов QTimer :: singleShot немедленно запускают все слоты - PullRequest
1 голос
/ 02 апреля 2020

У меня> 1 _сервисов, с которыми я хочу что-то сделать в функции "executeCheck (...)". Эта функция executeCheck должна вызываться с задержкой для каждой услуги на 1 с самого первого раза. Однако, если у меня есть, например, 3 службы (_services), executeCheck для всех 3 служб называется немедленно , а не с задержкой.

Кто-нибудь знает, почему это происходит сразу (I ( в настоящее время) имеет только основной QThread, в котором работает QTimer).

Пример кода:

int timeoutMs = 0;
for(auto& serviceContainer : _services) {
    Q_DEBUG_M() << "Perform check for " << serviceContainer.service->getServiceTypeDescription() << " in " << timeoutMs << "ms";

    serviceContainer.checkOngoing = true;
    QTimer::singleShot(timeoutMs, this, [this, &serviceContainer]() {
        performCheck(serviceContainer);
    });
    timeoutMs+=1000;
}

1 Ответ

0 голосов
/ 03 апреля 2020

Как вы указали в своем комментарии и своем вопросе, это зависит от EventQueue (EventL oop). По истечении QTimer (независимо от одиночного или обычного таймера) сработавший слот будет передан в EventQueue и обработан. Теперь, когда у вас работает только основной поток, у вас есть только один EventQueue (QTimers будет срабатывать также, если EventQueue заблокирован).

Теперь в вашем случае imaginge что-то блокирует основной поток чем-то (например, инициализация QML Stuff) более 3 секунд. Поэтому ваша EventQueue останавливается более чем на 3 секунды. Но QTimer радостно выдвигает Слоты, которые срабатывают в Очереди. Теперь после разблокирования потока обработка EventQueue продолжается, и он будет обрабатывать все слоты, выдаваемые QTimer «немедленно».

Простое решение для вас - выполнить проверки после init. Если это работает для вас, это нормально. В противном случае рассмотрите возможность получения асинхронной c проверки ваших услуг через QThread. QThread имеет свой собственный EventL oop (очередь). Таким образом, вы можете выполнить свои проверки вовремя и просто сообщить о результатах, которые будут получены, когда основной поток ответит снова. Я надеюсь, что это прояснит для вас.

...