2010-04-22 2 views
2

В Qt Мне нужно подключиться и проверить наличие обновлений на нескольких серверах, и для этого я использую QNetworkAccessManager. Проблема в том, что я не хочу подключаться к следующему URL-адресу, пока текущий запрос не ответит и не будет завершен. Моя первая идея состояла в том, чтобы использовать цикл, как показано ниже, но тогда у меня есть проблема с тем, что я не хочу подключаться к следующему URL-адресу до тех пор, пока ток не будет завершен.Запустить несколько запросов URL в цикле в Qt

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-адрес завершен. Проблема с этим решением заключается в том, что у меня есть некоторые проблемы с тем, что многие соединения() и finishedSlot() будут открыты одновременно с тем, что материал, который я создаю в этих методах, не будет удален, и это вызовет проблемы с памятью. Я знаю, что это имеет какое-то отношение к query.exec (sqlString), потому что без этого все работает так, как должно. Но почему это так сильно отличается от этих двух решений?

Как бы вы это разрешили?

+0

Утечка может возникнуть при создании экземпляра QNetworkAccessManager и его никогда не удалять. Вы можете подключить сигнал законченного() сигнала QNetworkAccessManager к его слоту deleteLater или сделать некоторые пользовательские вещи или выполнить очистку при уничтожении родителя. – drahnr

ответ

0

Запуск новых запросов из готового слота() звучит хорошо. Просто убедитесь, что также ответ-> deleteLater(), когда один из ответов завершен.

+0

Спасибо! Да, использование deleteLater() в finishedSlot() - хорошая идея. Я добавил дополнительную информацию выше. Похоже, проблема с утечкой памяти связана с QSqlQuery.exec(), поскольку это работает в первом решении, но во втором, похоже, утечка памяти. Вы видите что-то не так со вторым решением? – Martin

+0

Ах. Вы создаете новый QNetworkAccessManager, который я вижу. У вас должен быть один QNetworkAccessManager для каждого приложения! Он может обрабатывать множество запросов без проблем. – guruz

 Смежные вопросы

  • Нет связанных вопросов^_^