Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Qt5]Qthread и асинхронный запрос, Нужен совет 
:(
    Опции темы
dix75
Дата 8.4.2014, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 462
Регистрация: 17.7.2007

Репутация: 1
Всего: 1



Добрый день!

Нужен совет.

Имеется несколько веб-сервисов. Проблема сервисы могут быть недоступны.
Необходимо последовательно перебирать сервисы и слал запросы до тех пор пока не получу данные.

Наисано базовый класс сервисов, класс заглушка и все реализации сервисов.
В написании класса перебирающего сеервисы возникла проблема.
Логика следующая
 - создается поток
 - в потоке перебираются сервисы если данные получены, поток завершается.

Но проблема в том, что сервисы не испускают сигналы, хотя должны.

Работа классов сервисов проверена тестами.




--------------------
save your mind
PM MAIL   Вверх
bsa
Дата 9.4.2014, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



dix75, это стандартная проблема с потоками и сигналами в Qt. Чтобы работали сигналы, нужно сделать moveToThread для всех объектов, кто их генерит.
PM   Вверх
dix75
Дата 9.4.2014, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 462
Регистрация: 17.7.2007

Репутация: 1
Всего: 1



bsa,  Так эти объекты создаются внутри потока


--------------------
save your mind
PM MAIL   Вверх
vinter
Дата 9.4.2014, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 3
Всего: 56



слишком абстрактно описана проблема, помочь при таком описании весьма проблематично. 


--------------------
Мой блог
PM MAIL WWW   Вверх
bsa
Дата 10.4.2014, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



dix75, внутри потока (run()) или внутри конструктора потока? Конструктор потока запускается из другого потока!
PM   Вверх
dix75
Дата 12.4.2014, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 462
Регистрация: 17.7.2007

Репутация: 1
Всего: 1



bsa, 
Внутри run() 



--------------------
save your mind
PM MAIL   Вверх
bsa
Дата 14.4.2014, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



dix75, а кто у них parent? Просто имей в виду, что если парент у них QThread, то это все равно, что создан в другом потоке. 
PM   Вверх
dix75
Дата 14.4.2014, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 462
Регистрация: 17.7.2007

Репутация: 1
Всего: 1



bsa, 

parent у них QObject;


--------------------
save your mind
PM MAIL   Вверх
Guinness
Дата 15.4.2014, 08:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 21.6.2009
Где: Зеленоград

Репутация: 2
Всего: 10



dix75, можно тело функции run посмотреть?
PM MAIL   Вверх
dix75
Дата 15.4.2014, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 462
Регистрация: 17.7.2007

Репутация: 1
Всего: 1



Выложил всю конструкцию

Код

class Worker : public QObject {
    Q_OBJECT

public:
    Worker(QObject* parent): QObject (parent){}

    void execute(QString const& s) {
        emit finishedWork("The end");
    }

signals:
    void finishedWork(QString const& str);
};



Код

class WorkerThread1 : public QThread {
    Q_OBJECT

void run() override {
    Worker* w = new Worker(this);
    connect(w, SIGNAL(finishedWork(QString const&)), this, SLOT(finishedWork(QString const&)));
    w->execute("bla");
}

signals:
    void resultReady(unsigned i);

private slots:
    void finishedWork(QString const&) {
        qDebug() << "cool";
        emit resultReady(5);
    }

public:
    WorkerThread1() {
    }
};


Код

class List : public QObject {
    Q_OBJECT

public:
    virtual void doExecute() {
        WorkerThread1 *workerThread = new WorkerThread1;
        connect(workerThread, &WorkerThread1::resultReady, this, &List::handleResults);
        connect(workerThread, &WorkerThread1::finished, workerThread, &QObject::deleteLater);
        workerThread->start();
    }
private slots:
    void resultReady(unsigned i) {
        qDebug() << "It works";
    }
    void handleResults(int) {
        qDebug() << "It works 2";
    }
};



Код

 List list;
list.doExecute();
QVERIFY(waitForSignal(&list, SIGNAL(resultReady(unsigned i)), 5000));


Да в отладчике пишет что разные треды. И как сделать одним тредом.

Это сообщение отредактировал(а) dix75 - 15.4.2014, 14:00


--------------------
save your mind
PM MAIL   Вверх
Guinness
Дата 15.4.2014, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 21.6.2009
Где: Зеленоград

Репутация: 2
Всего: 10



dix75, косяк здесь в этой строчке:
Код

Worker* w = new Worker(this);

Сам QThread находится в другом потоке, не в том, которой запускается методом run(). Нужно просто не передавать в конструктор this.
PM MAIL   Вверх
dix75
Дата 15.4.2014, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 462
Регистрация: 17.7.2007

Репутация: 1
Всего: 1



Теперь к сути проблемы

Код

class Worker : public QObject {
    Q_OBJECT

public:
    Worker(QObject* parent): QObject (parent){}
    Worker(){

    }

    void execute(QString const& s) {
        auto manager = new QNetworkAccessManager;
        connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finished(QNetworkReply*)));
        manager->get(QNetworkRequest(QUrl("http://qt-project.org")));
    }

signals:
    void finishedWork(QString const& str);

public slots:
    void finished(QNetworkReply* reply) {
        qDebug() << "Reply";
        emit finishedWork("word");
    }

};


Manager не работает



--------------------
save your mind
PM MAIL   Вверх
vinter
Дата 15.4.2014, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 3
Всего: 56



блин, ну сколько можно так использовать Qt треды. Почему их никто не использует правильно?

Код

class Worker : public QObject {
    Q_OBJECT

public:
    Worker(QObject* parent): QObject (parent){}

    void execute(QString const& s) {
        emit finishedWork("The end");
    }

signals:
    void finishedWork(QString const& str);
};

Код

class List : public QObject {
    Q_OBJECT

public:
    virtual void doExecute() {
        Worker *worker = new Worker(this);
        
        connect(worker, &WorkerThread1::finishedWork, this, &List::handleResults);
        connect(this, &List::startWorker, worker, Worker::execute);
        worker->moveToThread(&m_WorkerThread);
        m_WorkerThread.start();
        emit starWorker();
    }
signals:
void startWorker();
private slots:
    void resultReady(unsigned i) {
        qDebug() << "It works";
    }
    void handleResults(QString) {
        qDebug() << "It works 2";
    }
private:
QThread m_WorkerThread;
};


Не проверял, но суть должна быть ясна.

Добавлено через 2 минуты и 42 секунды
Цитата(dix75 @  15.4.2014,  15:56 Найти цитируемый пост)
Manager не работает

может быть твой Worker находится в потоке чья очередь сообщений в данный момент ожидает чего-то и ты просто не можешь получить сообщение от мэнеджера?


--------------------
Мой блог
PM MAIL WWW   Вверх
dix75
Дата 15.4.2014, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 462
Регистрация: 17.7.2007

Репутация: 1
Всего: 1



Цитата(vinter @  15.4.2014,  15:24 Найти цитируемый пост)
блин, ну сколько можно так использовать Qt треды. Почему их никто не использует правильно?


ну во-первых  это задокументированная возможность.
Код

class WorkerThread : public QThread
{
    Q_OBJECT
    void run() Q_DECL_OVERRIDE {
        QString result;
        /* expensive or blocking operation  */
        emit resultReady(result);
    }
signals:
    void resultReady(const QString &s);
};

void MyObject::startWorkInAThread()
{
    WorkerThread *workerThread = new WorkerThread(this);
    connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    workerThread->start();
}

см. Qthread.

Во вторых твой код тоже не работает



--------------------
save your mind
PM MAIL   Вверх
vinter
Дата 15.4.2014, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 3
Всего: 56



Цитата(dix75 @  15.4.2014,  17:01 Найти цитируемый пост)
ну во-первых  это задокументированная возможность.

эта часть документации добавлена после глупой статьи на woboq, автором этой же статьи. Наследовать QThread, чтобы сделать WorkerThread - не правильно. Как с точки зрения ООП, так и с точки зрения тех, кто Qt писал изначально. Не предназначен он для этого.

Цитата(dix75 @  15.4.2014,  17:01 Найти цитируемый пост)
Во вторых твой код тоже не работает

ну код у тебя не мой, моя только идея. Вероятно ты её не так используешь  smile  

Это сообщение отредактировал(а) vinter - 15.4.2014, 16:21


--------------------
Мой блог
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0543 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.