QnetworkAccessManager线程永远不会完成

QNetworkAccessManager threads never finish

本文关键字:线程 永远 QnetworkAccessManager      更新时间:2023-10-16

我知道,在版本4.8中,每个http请求都可以运行自己的线程。
我正在执行一个链接检查器应用程序,该应用程序在一段时间内执行了很多HTTP请求,我在Windows任务管理器中注意到,我的应用程序随着时间的推移使用了1600多个线程,并且数字永远不会降低,只有直到它崩溃为止该应用。(我猜那是原因。)

我的问题是,QNetworkAccessManager是否可以选择使用线程池?
还是可以选择在完成其HTTP请求后清洁线程?

这是主要循环:

while(!rpm_urlStack->isEmpty())
{
    QString url = rpm_urlStack->top();
    //define the reply
    QNetworkReply *reply;
    rpm_urlStack->pop();
    QString urlForReq(url);
    bool returnVal = true;
    QNetworkRequest request;
    request.setUrl(QUrl(urlForReq));
    request.setRawHeader("User-Agent", USER_AGENT.toUtf8());
    request.setRawHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
    request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    request.setRawHeader("Accept-Language", "en-us,en;q=0.5");
    request.setRawHeader("Connection", "Keep-Alive");
    QEventLoop loop;
    reply = m_networkManager->get(request);
    connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exit();
    if(!loop.isRunning()) {
        loop.exec();
    }
    RequestFinishedHandler(reply);
    // this is how I delete the reply object
    delete reply;
}
RequestFinishedHandler(QNetworkReply *reply)
{
    if (reply->error() > 0) {
        QNetworkReply::NetworkError networkError = reply->error();
        QString err = reply->errorString();
    } else {
        QVariant vStatusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        QMutexLocker lock(_pMutex); // _pMutex defined as class member
        char *buffer;
        buffer = getCurrentDateTime();
        QTextStream out(m_file);
        out << buffer << "  " << _sCurrentUrl << "n";
        lock.unlock();
        if(vStatusCodeV.toInt() == 200) {
            QString ApiResponse;
            QByteArray data;
            data=reply->readAll();
            ApiResponse.append(QString::fromUtf8(data));
        }
    }
}

似乎必须从事件循环中调用deleteLater方法,该方法必须重新获得执行控制以处理垃圾收集。

也许您应该重构代码以使事件循环更换您的时循环。另外,由于您不使用finished插槽来处理回复,也许您可以在RequestFinishedHandler函数末尾直接删除答复。