2010-09-23 4 views
1

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

У меня возникли проблемы с моим решением. На некоторых платформах Symbian мой QTimer слишком быстро сигнализирует тайм-аут (например, через 1 секунду, когда тайм-аут составляет 30 секунд). Это обычно происходит, если моя загрузочная загрузка HTTP Post велика или я загружаю файл через GET (запрос занимает некоторое время). Я хочу отметить, что тот же код отлично работает на некоторых устройствах (S60 3rd ed.), Но, с другой стороны, некоторые устройства (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(); 
    } 
} 

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

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

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

Платформа: Symbian S60 3rd/5th Edition

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

+0

Возможно, это ошибка в Qt, но не уверен. Возможно, опубликуйте сообщение об ошибке. Во всяком случае, я бы посоветовал не использовать этот рекурсивный цикл событий, чтобы делать что-то. Это усложняет ситуацию и (как вы сказали) может испортить вещи. – guruz

+0

Спасибо за ответ. – Routa

+0

Кто-нибудь знает, какой ребенок проблем может создать локальный цикл событий? Например: 1. Могу ли я потерять некоторые события? 2. Могу ли я получить одно и то же событие дважды? 3. Может ли QTimer изменить свое поведение? 4. Некоторые проблемы с QNAM (например, завершенные не сигнализированы) – Routa

ответ

0

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