QNetworkAccessManager内存问题

QNetworkAccessManager memory issues

本文关键字:问题 内存 QNetworkAccessManager      更新时间:2023-10-16

我正在开发一个应用程序,该应用程序使用QtNetworkAccessManager向服务器发送请求并存储回复。我已经让它工作了,但内存使用量持续增加,直到它阻塞了整个电脑。我认为问题与调用deletelater()和事件循环有关,但我不知道如何解决它。以下是代码:

main.cpp

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    ReadConfig();
    Ethernet M2;
    return a.exec();
}

以太网.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);
};

以太网.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();
}

如果有任何建议,我将不胜感激。非常感谢。

如果您的类不是线程,那么它不应该继承QThread。从QObject继承它,如果不能,则启动M2线程。现在,Ethernet的线程循环不起作用,而且网络回复似乎与Ethernet事件循环有关联(删除它们的请求被发布到未启动的Ethernet事件循环)。

或者更确切地说,你的插槽根本没有执行过,所以会创建网络回复,但它们永远不会被删除,因为你的插槽从未执行过(因为上述原因),所以如果我没有错的话,网络回复在主线程中,所以deleteLater应该正确地删除它们,但它永远不会被调用。

您需要从QObject中对以太网进行子类化才能正确使用事件循环

您不能创建QNetworkAccessManager的多个对象。正如文件中所说:"一个QNetworkAccessManager应该足以用于整个Qt应用程序。"参考链接。如果您使以太网类的多个对象,那么它将产生内存问题。您还需要将QObject作为以太网的基类。

manager = new QNetworkAccessManager(this);
this (Ethernet) must have QObject as base class.