QNetworkAccessManager 内存问题
QNetworkAccessManager memory issues
我正在开发一个使用 QtNetworkAccessManager 向服务器发送请求并存储回复的应用程序。我已经让它工作了,但内存使用量不断增加,直到它阻塞了整个 PC。我认为问题与调用 deletelater() 和事件循环有关,但我看不出如何解决它。这是代码:
main.cpp
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ReadConfig();
Ethernet M2;
return a.exec();
}
Ethernet.h
class Ethernet : public QObject
{
Q_OBJECT
public:
Ethernet();
~Ethernet();
QTimer *timer;
private
QNetworkAccessManager *manager;
public slots:
void Cycle();
void replyAuthenticationRequired(QNetworkReply *reply, QAuthenticator *auth);
void replyFinished(QNetworkReply *reply);
};
Ethernet.cpp
Ethernet::Ethernet()
{
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(Cycle()));
timer->start(1000);
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(replyAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}
void Ethernet::Cycle()
{
for (BYTE i=0; i< NUM_TOTAL_VEHICLES; i++)
{
FailCheck(i,FILTER_VALUE_PRIORITY_A1);
FailCheck(i,FILTER_VALUE_PRIORITY_A);
FailCheck(i,FILTER_VALUE_PRIORITY_B);
FailCheck(i,FILTER_VALUE_PRIORITY_C);
}
}
void Ethernet::FailCheck (BYTE coach, BYTE priority)
{
//Build a valid URL
QString qsURL = "http://";
...
..
.
//
manager->get(QNetworkRequest(QUrl(qsURL)));
}
void Ethernet::replyAuthenticationRequired(QNetworkReply *reply, QAuthenticator *auth)
{
if(!reply->error())
{
auth->setUser(DB_USR);
auth->setPassword(DB_PWD);
}
reply->deleteLater();
}
void Ethernet::replyFinished (QNetworkReply *reply)
{
if(!reply->error())
{
//Do some task with the reply;
}
reply->deleteLater();
}
如有任何建议,我将不胜感激。谢谢!
您需要从 QObject 继承 Ethernet 才能正确使用事件循环
您不能创建多个 QNetworkAccessManager 对象。正如文件所说 "One QNetworkAccessManager should be enough for the whole Qt application."
Reference link。如果你制作多个以太网对象 class 那么它会产生内存问题。您还需要将 QObject 作为以太网的基础 class.
manager = new QNetworkAccessManager(this);
this (Ethernet) must have QObject as base class.
如果您的 class 不是线程,那么它不应继承 QThread
。从 QObject
继承它,或者,如果你不能,启动你的 M2
线程。现在你的 Ethernet
线程循环不起作用 并且网络回复似乎与你的 Ethernet
事件循环有亲和力(删除它们的请求发布到Ethernet
事件循环,未启动).
或者更确切地说,你的槽根本就没有被执行过,所以网络回复被创建但它们永远没有机会被删除,因为你的槽从未被执行过(由于上述原因)所以如果我不是误认为网络回复存在于主线程中,因此 deleteLater
应该正确删除它们,但它永远不会被调用。
我正在开发一个使用 QtNetworkAccessManager 向服务器发送请求并存储回复的应用程序。我已经让它工作了,但内存使用量不断增加,直到它阻塞了整个 PC。我认为问题与调用 deletelater() 和事件循环有关,但我看不出如何解决它。这是代码:
main.cpp
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ReadConfig();
Ethernet M2;
return a.exec();
}
Ethernet.h
class Ethernet : public QObject
{
Q_OBJECT
public:
Ethernet();
~Ethernet();
QTimer *timer;
private
QNetworkAccessManager *manager;
public slots:
void Cycle();
void replyAuthenticationRequired(QNetworkReply *reply, QAuthenticator *auth);
void replyFinished(QNetworkReply *reply);
};
Ethernet.cpp
Ethernet::Ethernet()
{
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(Cycle()));
timer->start(1000);
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(replyAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}
void Ethernet::Cycle()
{
for (BYTE i=0; i< NUM_TOTAL_VEHICLES; i++)
{
FailCheck(i,FILTER_VALUE_PRIORITY_A1);
FailCheck(i,FILTER_VALUE_PRIORITY_A);
FailCheck(i,FILTER_VALUE_PRIORITY_B);
FailCheck(i,FILTER_VALUE_PRIORITY_C);
}
}
void Ethernet::FailCheck (BYTE coach, BYTE priority)
{
//Build a valid URL
QString qsURL = "http://";
...
..
.
//
manager->get(QNetworkRequest(QUrl(qsURL)));
}
void Ethernet::replyAuthenticationRequired(QNetworkReply *reply, QAuthenticator *auth)
{
if(!reply->error())
{
auth->setUser(DB_USR);
auth->setPassword(DB_PWD);
}
reply->deleteLater();
}
void Ethernet::replyFinished (QNetworkReply *reply)
{
if(!reply->error())
{
//Do some task with the reply;
}
reply->deleteLater();
}
如有任何建议,我将不胜感激。谢谢!
您需要从 QObject 继承 Ethernet 才能正确使用事件循环
您不能创建多个 QNetworkAccessManager 对象。正如文件所说 "One QNetworkAccessManager should be enough for the whole Qt application." Reference link。如果你制作多个以太网对象 class 那么它会产生内存问题。您还需要将 QObject 作为以太网的基础 class.
manager = new QNetworkAccessManager(this);
this (Ethernet) must have QObject as base class.
如果您的 class 不是线程,那么它不应继承 QThread
。从 QObject
继承它,或者,如果你不能,启动你的 M2
线程。现在你的 Ethernet
线程循环不起作用 并且网络回复似乎与你的 .Ethernet
事件循环有亲和力(删除它们的请求发布到Ethernet
事件循环,未启动)
或者更确切地说,你的槽根本就没有被执行过,所以网络回复被创建但它们永远没有机会被删除,因为你的槽从未被执行过(由于上述原因)所以如果我不是误认为网络回复存在于主线程中,因此 deleteLater
应该正确删除它们,但它永远不会被调用。