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 应该正确删除它们,但它永远不会被调用。