Проблемы тайм-аута QTimer с QEventLoop и QNAM - PullRequest
1 голос
/ 23 сентября 2010

Я создал свой собственный класс HTTP, который использует QNAM и предоставляет средства для отправки HTTP-запросов. Он использует QEventLoop для синхронизации и QTimer для тайм-аутов.

У меня мало проблем с моим решением. На некоторых платформах Symbian мой QTimer сигнализирует слишком быстро (например, через 1 секунду, когда время ожидания составляет 30 секунд). Обычно это происходит, если моя загрузка HTTP Post велика или я загружаю файл через GET (запрос занимает некоторое время). Хочу отметить, что один и тот же код отлично работает на определенных устройствах (S60, 3-е изд.), Но, с другой стороны, некоторые устройства (5-е издание) почти постоянно получают эту ошибку.

Вот фрагмент кода:

MyHttp::MyHttp(QObject *parent) : QObject(parent)
{
    m_Timer.setSingleShot(true);
    connect(&m_Manager, SIGNAL(finished(QNetworkReply*)), SLOT(OnFinished(QNetworkReply*)));
    connect(&m_Timer, SIGNAL(timeout()), SLOT(OnTimeout()));
}


void MyHttp::Post(const QString &data)
{
    m_RetCode = 0;
    QNetworkRequest request(url);
    m_Reply = m_Manager.post(request, data.toAscii());  // QPointer<QNetworkReply> m_Reply

    m_Timer.start(30*1000); 
    m_EventLoop.exec(); // Synchronization point
}


void MyHttp::OnFinished(QNetworkReply * reply)
{
    // Handle response / Timeout / Errors

    reply->deleteLater(); // Use deleteLater() as adviced in the documentation
    StopWaiting();
}


void MyHttp::StopWaiting()
{
    m_Timer.stop();
    m_EventLoop.exit();
}

void MyHttp::OnTimeout()
{
    m_RetCode = TIMEOUT; // #define TIMEOUT 50000

    if(m_Reply.isNull() == false)
    {
        // Abort reply
        m_Reply->abort();
    }
}

Лично я думаю, что одно из следующего может вызвать проблему:

  • повторный вход в локальный цикл событий портит сигналы
  • Я использую один и тот же QNAM несколько раз (несколько запросов во время одного сеанса). Это необходимо, потому что, если я уничтожу QNAM, мой сеанс прекратится на стороне сервера.

Кто-нибудь может увидеть некоторые ошибки, которые могут вызвать такое поведение?

Платформа: Symbian S60, 3-е / 5-е издание

Инструменты: Nokia Qt SDK

1 Ответ

0 голосов
/ 26 декабря 2011

У меня точно такие же проблемы. Использование local для метода QEventLoop приводит к странным результатам, например, блокирует некоторые события, которые нужно обработать (и затем цикл никогда не завершается), или, как объяснено, провоцирует QTimer на слишком быстрый запуск до истечения времени ожидания (а затем цикл выходит слишком рано). Использование поля экземпляра для цикла, инициализированного один раз в конструкторе родительского объекта цикла, похоже, решает проблему. Я нахожусь на Qt 4.6.3 и Symbian S60 / 5th Edition.

...