在 Qt 中循环运行多个 url 请求

Posted

技术标签:

【中文标题】在 Qt 中循环运行多个 url 请求【英文标题】:Run several url requests in a loop in Qt 【发布时间】:2010-04-22 13:56:32 【问题描述】:

在 Qt 中,我需要连接并检查多台服务器上的更新,为此我正在使用 QNetworkAccessManager。问题是在当前请求得到答复并完成之前,我不想连接到下一个 url。我的第一个想法是使用像下面这样的循环,但是我遇到了一个问题,即在当前完成之前我不想连接到下一个 url。

void connect() 
    for (int index = 0; index < 20; index++) 
        //I need to use this QSqlQuery to get some data here
        QSqlQuery query;
        QString sqlString = getSql(index);
        query.exec(sqlString);
        .....

        if (needUpdate(index))  //Check if I need to connect to this url
            QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager(this); 
            connect(networkAccessManager, SIGNAL(finished(QNetworkReply*)),this, SLOT(finishedSlot(QNetworkReply*)));
            QUrl url = getUrl(index); //Get the url based on the current index
            networkAccessManager->get(QNetworkRequest(url));
        
    
 

void finishedSlot(QNetworkReply* reply) 

//做更多的事情

我解决问题的另一个想法是这样构建它:

int index;

void connect() 
        /*I need to use this QSqlQuery to get some data here, 
          it works perfect when just looping like before, but when using 
          this solution I get memory problems, 
         it seems like it doesn't delete the query*/
        QSqlQuery query;
        QString sqlString = getSql(index);
        query.exec(sqlString);
        ..... 


    if (needUpdate(index))  //Check if I need to connect to this url
        QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager(this); 
        connect(networkAccessManager, SIGNAL(finished(QNetworkReply*)),this, SLOT(finishedSlot(QNetworkReply*)));
        QUrl url = getUrl(index); //Get the url based on the current index
        networkAccessManager->get(QNetworkRequest(url));
     else 
        index++;
        connect(); //Request next url
    


void finishedSlot(QNetworkReply* reply) 
//Do more stuff
    index++;
    connect(); //Request next url

现在在当前 url 完成之前不会请求下一个 url。这个解决方案的问题是我有一些问题,因为许多connection()和finishedSlot()将同时打开,我在这些方法中创建的东西不会被删除,这将导致内存问题。我知道它与 query.exec(sqlString) 有关,因为没有它,一切都会正常工作。但为什么这两种解决方案会有如此大的不同呢?

你会怎么解决这个问题?

【问题讨论】:

您的泄漏可能来自创建 QNetworkAccessManager 的实例并且从不删除它。您可以将 QNetworkAccessManager 的信号 finished() 信号连接到它的 deleteLater 插槽,或者做一些自定义的事情,或者在父级销毁时进行清理。 【参考方案1】:

从finished() 槽启动新请求听起来不错。 只需确保在其中一个回复完成后也执行回复->deleteLater()。

【讨论】:

谢谢!是的,在finishedSlot() 中使用deleteLater() 是个好主意。我在上面添加了更多信息。似乎内存泄漏问题与 QSqlQuery.exec() 有关,因为这在第一个解决方案中非常有效,但在第二个解决方案中似乎泄漏了内存。你能看出第二种解决方案有什么问题吗? 啊。我看到你正在创建一个新的 QNetworkAccessManager。每个应用程序应该有一个 QNetworkAccessManager!它可以毫无问题地处理多个请求。

以上是关于在 Qt 中循环运行多个 url 请求的主要内容,如果未能解决你的问题,请参考以下文章

sh bash脚本运行循环以从文件中读取随机URL和用户代理,并使用cURL运行请求。这可以从任何系统运行

并行执行多个 AJAX 请求,并在所有请求完成后运行一个函数

Asyncio RuntimeError:事件循环已关闭

在 qt 中创建另一个网络线程

Qt 循环中加入QCoreApplication::processEvents退出后台运行

多个 ajax 请求调用。