0

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

主文件

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();
}

我将不胜感激任何建议。谢谢!

4

3 回答 3

0

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

于 2016-05-10T07:57:27.923 回答
0

您不能创建 QNetworkAccessManager 的多个对象。正如文档所说“一个 QNetworkAccessManager 应该足以满足整个 Qt 应用程序。” 参考链接。如果您制作以太网类的多个对象,则会产生内存问题。您还需要将 QObject 作为以太网的基类。

manager = new QNetworkAccessManager(this);
this (Ethernet) must have QObject as base class.
于 2016-05-10T08:18:23.860 回答
0

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

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

于 2016-05-10T09:14:18.160 回答