0
votes

I am trying to multiple request with QNetworkAccessManager even I connect slots QNetworkAccessManager cant emit finished() signal.

Here is the code I implemented.

void GetNetwork::getAction(QStringList *urls, QList<QByteArray> *result)
{
    uint size=urls->size();

    multiGetResult=result;
    getUrls=urls;
    setFlags();

    for(uint x=0;x<size;x++)
    {
        int test=caluculateIndex(x);
       getNAM[test]->get(QNetworkRequest(QUrl(urls->at(x))));
    }


    //qDebug()<<reply->readAll();

    while (!waitWithFlag())  QThread::msleep(15);

    delete threadFlag;
}

bool GetNetwork::setMultipleGet(uint number)
{
    int diff=number-(getNAM.size()-1);

    if(((getNAM.size()-1)+diff)<0)
        return false;

    for(int i=0;i<diff;i++)
    {
        getNAM.append(new QNetworkAccessManager(this));
        connect(getNAM[getNAM.size()-1],SIGNAL(finished(QNetworkReply*)),this,SLOT(handleMultiRequest(QNetworkReply*)));
    }

    for(int i=diff;i<0;i++)
    {
        disconnect(getNAM[getNAM.size()-1],SIGNAL(finished(QNetworkReply*)),this,SLOT(handleMultiRequest(QNetworkReply*)));
        delete getNAM[getNAM.size()-1];
        getNAM.remove(getNAM.size()-1);
    }
    return true;
}

void GetNetwork::handleMultiRequest(QNetworkReply * reply)
{
    int index=getUrls->indexOf(reply->url().toString());

    if(reply->error()!=QNetworkReply::NoError||index==-1)
    {
        QString error=QString("Network Error file:%1 line:%2 error:%3")
                             .arg(__FILE__)
                             .arg(__LINE__)
                             .arg(reply->errorString());

        emit errorOccured(error);
        return;
    }

    multiGetResult->insert(index,reply->readAll());
    threadFlag[index]=true;
}

What's wrong in these codes? I cant figure it out.

Thank you.

2
Have you tried to hook the error signal? - lpapp
You must return to the event loop to have the request being executed and the result being reported. Your code with the while loop and sleep looks like you block the event loop (until the result arrived?), thus the request isn't executed at all. - Frank Osterfeld
I.e., sleep() blocks the event loop and thus any event processing including network I/O. Also in a UI application, sleep() in the main thread is really bad practice, as it makes the UI unresponsive. - Frank Osterfeld
no it waits untill all threads are done. but qnetworkaccessmanager doesnt emit finished signal and the function waits here for nothing.i just want to be sure that all gets are done end of the function. - Veysel Bekir Macit
the problem is about while "(!waitWithFlag()) QThread::msleep(10);" end of the function is there a way wait these gets until all of them are done? - Veysel Bekir Macit

2 Answers

1
votes

First of all you don't need a separate thread for QNetworkAccessManager as it internally runs in a separate thread (asynchronous) since Qt 4.8.1.

Secondly you are only connecting the last instance of QNetworkAccessManager with a finished slot, instead of doing that, connect each instance of QNetworkAccessManager with handleMultiRequest Slot and keep increasing the count whenever the slot is invoked. You don't need sleep and all that stuff, it is all event driven. So,

void GetNetwork::handleMultiRequest(QNetworkReply * reply)
{
    int index=getUrls->indexOf(reply->url().toString());

    if(reply->error()!=QNetworkReply::NoError||index==-1)
    {
        QString error=QString("Network Error file:%1 line:%2 error:%3")
                             .arg(__FILE__)
                             .arg(__LINE__)
                             .arg(reply->errorString());

        emit errorOccured(error);
        return;
    }

    count++;
   if(count == num_get_requests)
   {
       emit
         allDone()
   }
}
0
votes

and I changed fucntions like Adnan idea

void GetNetwork::handleMultiRequest(QNetworkReply * reply)
{
    int index=getUrls->indexOf(reply->url().toString());

    if(reply->error()!=QNetworkReply::NoError||index==-1)
    {
        QString error=QString("Network Error file:%1 line:%2 error:%3")
                             .arg(__FILE__)
                             .arg(__LINE__)
                             .arg(reply->errorString());

        emit errorOccured(error);
        return;
    }

    multiGetResult->insert(index,reply->readAll());
    threadDoneCounter++;
    if(threadDoneCounter==getUrls->size())
        emit threadsAreDone();
}

and

void GetNetwork::getAction(QStringList *urls, QList<QByteArray> *result)
{
    uint size=urls->size();

    multiGetResult=result;
    getUrls=urls;
    threadDoneCounter=0;

    for(uint x=0;x<size;x++)
    {
        int test=caluculateIndex(x);
       getNAM[test]->get(QNetworkRequest(QUrl(urls->at(x))));
    }



    QEventLoop eLoop;
    connect(this,SIGNAL(threadsAreDone()),&eLoop,SLOT(quit()));
    eLoop.exec();

    disconnect(this,SIGNAL(threadsAreDone()),&eLoop,SLOT(quit()));
}