QEventLoop和QNAM的QTimer超时问题
我创建了自己的HTTP类,它利用QNAM并提供发送HTTP请求的方法。它使用QEventLoop进行同步,使用QTimer进行超时 我的解决方案没有什么问题。在某些Symbian平台上,我的QTimer信号超时过快(例如,超时时间为30秒时,1秒后)。如果我的HTTP Post播放负载很大,或者通过GET下载文件(请求需要一些时间才能完成),通常会发生这种情况。我想指出的是,相同的代码在某些设备(S60第3版)上运行良好,但另一方面,一些设备(第5版)几乎一直都会出现此错误 以下是一段代码片段:QEventLoop和QNAM的QTimer超时问题,qt,timeout,qnetworkaccessmanager,qeventloop,Qt,Timeout,Qnetworkaccessmanager,Qeventloop,我创建了自己的HTTP类,它利用QNAM并提供发送HTTP请求的方法。它使用QEventLoop进行同步,使用QTimer进行超时 我的解决方案没有什么问题。在某些Symbian平台上,我的QTimer信号超时过快(例如,超时时间为30秒时,1秒后)。如果我的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();
}
}
MyHttp::MyHttp(QObject*parent):QObject(parent)
{
m_定时器设置单脉冲(真);
连接(&m_管理器、信号(已完成(QNetworkReply*))、插槽(已完成(QNetworkReply*));
连接(&m_定时器、信号(timeout())、插槽(OnTimeout());
}
void MyHttp::Post(常量QString和数据)
{
m_RetCode=0;
QNetworkRequest请求(url);
m_Reply=m_Manager.post(request,data.toAscii());//QPointer m_Reply
m_定时器启动(30*1000);
m_EventLoop.exec();//同步点
}
void MyHttp::OnFinished(QNetworkReply*reply)
{
//处理响应/超时/错误
reply->deleteLater();//使用文档中建议的deleteLater()
停止等待();
}
void MyHttp::StopWaiting()
{
m_Timer.stop();
m_EventLoop.exit();
}
void MyHttp::OnTimeout()
{
m_RetCode=TIMEOUT;//#定义超时
if(m_Reply.isNull()==false)
{
//中止应答
m_Reply->abort();
}
}
就我个人而言,我认为以下因素之一可能导致问题:
- 重新进入本地事件循环会弄乱信号
- 我多次使用同一个QNAM(在同一个会话中多次请求)。这是必需的,因为如果我破坏QNAM,我的会话将在服务器端中断
工具:诺基亚Qt SDK我也有类似的问题。使用QEventLoop方法的local会产生奇怪的结果,比如阻塞一些要处理的事件(然后循环从不退出),或者类似于解释的那样,在超时之前激发QTimer太快(然后循环过早退出)。 在循环的父对象的构造函数中为循环使用一次初始化的实例字段,似乎可以解决这个问题。
我使用的是Qt 4.6.3和Symbian S60/5th Edition。可能是Qt中的一些错误,但不确定。也许会给他们发个错误报告。无论如何,我建议不要使用这种递归事件循环方式来做事情。它使事情复杂化,而且(正如你所说)可能会把事情搞砸。有人知道本地事件循环会造成什么样的问题吗?例如:1。我能输掉一些比赛吗?2.我可以参加两次同样的活动吗?3.它会导致QTimer改变其行为吗?4.QNAM的一些问题(例如,未发出完工信号)