Проблемы с тайм-аутом QTimer с QEventLoop и QNAM

Я создал свой собственный 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


person Routa    schedule 23.09.2010    source источник
comment
Возможно, это какая-то ошибка внутри Qt, но не уверен. Может быть, отправьте им отчет об ошибке. В любом случае, я бы посоветовал не использовать этот способ рекурсивного цикла обработки событий. Это все усложняет и (как вы сказали) может все испортить.   -  person guruz    schedule 24.09.2010
comment
Кто-нибудь знает, какой ребенок проблем может создать локальный цикл событий? Например: 1. Могу ли я проиграть какие-то события? 2. Могу ли я получить одно и то же событие дважды? 3. Может ли он заставить QTimer изменить свое поведение? 4. Некоторые проблемы с QNAM (например, завершено без сигнала)   -  person Routa    schedule 29.09.2010


Ответы (1)


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

person Cédric NICOLAS    schedule 26.12.2011