Russian Qt Forum
Ноябрь 27, 2024, 12:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Баг QNetworkAccessManager или кривые руки?  (Прочитано 10939 раз)
Sanya
Гость
« : Июнь 24, 2010, 16:13 »

Доброго времени суток!

Наткнулся на такую штуку: если закрывать приложение до того как придет ответ от сервера, то класс формы закрывается, а вот приложение продолжает висеть в памяти в ввиду наличия незавершенных потоков.
Привожу тестовый пример. На разных машинах возможно надо будет поиграться значением таймера немного.

Код
C++ (Qt)
class MainWindow : public QMainWindow {
   Q_OBJECT
public:
   MainWindow(QWidget *parent = 0);
   ~MainWindow();
 
protected:
   void changeEvent(QEvent *e);
 
private:
   Ui::MainWindow *ui;
   QNetworkReply *reply;
   QNetworkAccessManager *manager;
 
};
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);
 
   QUrl    address("http://www.ya.ru/");
   manager = new QNetworkAccessManager(this);
   reply = manager->get(QNetworkRequest(address));
   connect(reply, SIGNAL(finished()), this, SLOT(close()));
 
   QTimer  *timer = new QTimer(this);
   timer->start(100);
   connect(timer, SIGNAL(timeout()), this, SLOT(close()));
 
}
 

после запуска такой программы она все еще "висит" после "выхода".

Вопрос: это баг или я что-то неправильно делаю?
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #1 : Июнь 24, 2010, 16:36 »

попробуй в деструкторе для MainWindow вызвать deleteLater() для QNetworkAccessManager'a.
Записан

kubuntu/Win7/x64/NetBeans
Sanya
Гость
« Ответ #2 : Июнь 24, 2010, 16:42 »

пробовал

и
manager->deleteLater();
и
reply->abort();
reply->deleteLater();

безрезультатно
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #3 : Июнь 24, 2010, 16:47 »

естественно, покурите про deleteLater() он удалит объект только после того как на него не будет ничего ссылаться, и завершаться процессы связанные с объектом, удали его жестко
Код:
delete manager;

Но возможно Exception словишь.
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #4 : Июнь 24, 2010, 16:49 »

естественно, покурите про deleteLater() он удалит объект только после того как на него не будет ничего ссылаться, и завершаться процессы связанные с объектом, удали его жестко
Код:
delete manager;

Но возможно Exception словишь.

Note: After the request has finished, it is the responsibility of the user to delete the QNetworkReply object at an appropriate time. Do not directly delete it inside the slot connected to finished(). You can use the deleteLater() function.

Да и сам проверял, было время, ловил ещё как Улыбающийся
Записан

kubuntu/Win7/x64/NetBeans
Sanya
Гость
« Ответ #5 : Июнь 24, 2010, 16:58 »

во-во!

я даже пробовал делать manager не динамическим и внутри конструктора - т.е. заведомое жесткое убийство по отработке конструктора и все равно успевает нахадить.
Записан
BRE
Гость
« Ответ #6 : Июнь 24, 2010, 17:08 »

А если так?
Код
C++ (Qt)
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);
 
   QUrl    address("http://www.ya.ru/");
   manager = new QNetworkAccessManager(this);
   reply = manager->get(QNetworkRequest(address));
   connect(reply, SIGNAL(finished()), qApp, SLOT(quit()));
 
   QTimer  *timer = new QTimer(this);
   timer->start(100);
   connect(timer, SIGNAL(timeout()), qApp, SLOT(quit()));
 
}
 
Записан
Sanya
Гость
« Ответ #7 : Июнь 24, 2010, 17:12 »

все тоже - "висит"

Может быть как "костыль": как-то(я просто не знаю как) получить список всех потоков приложения и послать им quit()?
Записан
BRE
Гость
« Ответ #8 : Июнь 24, 2010, 17:15 »

все тоже - "висит"

Может быть как "костыль": как-то(я просто не знаю как) получить список всех потоков приложения и послать им quit()?
Покажи main.cpp
Записан
Sanya
Гость
« Ответ #9 : Июнь 24, 2010, 17:19 »

Код
C++ (Qt)
   QApplication a(argc, argv);
   MainWindow w;
   w.show();
   return a.exec();
 
это тестовая версия на просто приложении с GUIем
Записан
BRE
Гость
« Ответ #10 : Июнь 24, 2010, 17:23 »

Выложи пожалуйста этот тест в виде архива (все файлы + .pro), что бы не нужно было копи-пастить.
И скажи на какой ты платформе это пробуешь и версию Qt.
Записан
Sanya
Гость
« Ответ #11 : Июнь 24, 2010, 17:32 »

Qt 4.6.2 + Qt Creator
Windows XP SP3
Записан
BRE
Гость
« Ответ #12 : Июнь 24, 2010, 17:39 »

А проверь так:
Код
C++ (Qt)
MainWindow::~MainWindow()
{
   delete manager;
   delete ui;
}
 
Записан
Sanya
Гость
« Ответ #13 : Июнь 24, 2010, 17:42 »

и это пробовал .... все тоже
Записан
Kolobok
Гость
« Ответ #14 : Июнь 24, 2010, 17:55 »

Qt 4.6.2 + Qt Creator
Windows 7

не висит.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.214 секунд. Запросов: 23.