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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QNetworkAccessManager и QThread  (Прочитано 13473 раз)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


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


Просмотр профиля
« : Июнь 25, 2009, 16:20 »

Подскажите пожалуйста как их подружить, если я организовываю скачивание в главном потоке то всё отлично, если пытаюсь сделать закачку в вторичном потоке то всё плохо вот исходник

Код:
#include <QtCore/QCoreApplication>

#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDebug>
#include <QFile>
#include <QThread>


#define USAGE QT_TRANSLATE_NOOP("threadDownload::main", "usage: %s <link> <file name>")

class ThreadHttpDownload : public QThread
{
    Q_OBJECT

    public:
        ThreadHttpDownload(QObject *parent,QString link);

        QNetworkReply *reply;
        QFile file;

        QString link;
        void run();

    private:

    private slots:
        void readyRead();
        void replyFinished(QNetworkReply*);
};

ThreadHttpDownload::ThreadHttpDownload(QObject *parent,QString _link)
        :QThread(parent)
{
     link = _link;
}

void ThreadHttpDownload::run()
{

    file.setFileName("download.file");
    file.open(QIODevice::WriteOnly);

     QNetworkRequest request;  // Формируем запрос
     request.setUrl(QUrl(link));


     QNetworkAccessManager manager;
     manager.moveToThread(this);

     reply = manager.get(request); //Отправляем запрос
     reply->moveToThread(this);

     connect(&manager, SIGNAL(finished(QNetworkReply*)),
         this, SLOT(replyFinished(QNetworkReply*)));
     connect(reply,SIGNAL(readyRead()),this,SLOT(readyRead()));

     exec();
}


void ThreadHttpDownload::readyRead()
{
        qDebug() << reply->size();
        file.write(reply->readAll());
}

void ThreadHttpDownload::replyFinished(QNetworkReply *reply)
{
    if (reply->error())
    {
        qDebug() << "error download" << reply->errorString();
        QCoreApplication::quit();
    }else
    {
        qDebug() << "download complete";
        file.close();
        QCoreApplication::quit();
    }
}

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        qDebug(USAGE, argv[0]);
        return 0;
    }

    QCoreApplication a(argc, argv);

        ThreadHttpDownload *th = new ThreadHttpDownload(0,argv[1]);
        th->start();

    return a.exec();
}

#include <main.moc>


вот в этом куске всё падает

file.write(reply->readAll());

где я туплю Непонимающий, уже несколько дней разобраться немогу Улыбающийся
Записан
SABROG
Гость
« Ответ #1 : Июнь 25, 2009, 16:51 »

У меня ничего не падает.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


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


Просмотр профиля
« Ответ #2 : Июнь 25, 2009, 19:46 »

Уменя Qt 4.5.0 MinGW или gcc Windows Vista падает с такой ошибкой
Код:
C:\threadDownload4\debug>threadDownload5.exe http://127.0.0.1/AdobePhotoshopCS4.
rar
32768
32768
0
32768
32768
ASSERT: "d->ref == 1" in file tools\qlistdata.cpp, line 123

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

или просто молча, ещё под OpenSUSE 11.1 собирал падает с ошибкой сигментирования.

может Qt обновить...
Записан
SABROG
Гость
« Ответ #3 : Июнь 25, 2009, 21:46 »

У меня не упала видимо потому, что я в release собирал. Завтра посмотрю еще раз.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


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


Просмотр профиля
« Ответ #4 : Июнь 25, 2009, 21:48 »

Ну вобщем обновил я и Qt до 4.5.2 и MinGW вместе сним, пересобрал софт всё тоже. Пробовал в обоих сборках и в debug и release.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


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


Просмотр профиля
« Ответ #5 : Июнь 25, 2009, 21:56 »

Да забыл сказать падает с файлами большого размер я пытаюсь скачать 2гб.
« Последнее редактирование: Июнь 26, 2009, 08:15 от ecspertiza » Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


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


Просмотр профиля
« Ответ #6 : Июнь 26, 2009, 09:25 »

Кажется справился, помог метод "Мюнхаузена" Улыбающийся В конструкторе потока прописал moveToThread(this) и вроде как заработало, SABROG, спасибо в твоём блоге прочитал )))
Записан
SABROG
Гость
« Ответ #7 : Июнь 26, 2009, 10:39 »

Вообще странно всё это:

Код:
[New thread 4676.0x1218]
[New thread 4676.0x13d8]
[New thread 4676.0x12b8]
[New thread 4676.0x150]
2572
4380
5840
7300
7300
0
7300
7300
19020
0
0
0
0
0
0
0
0
0
0
0
4380
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
18980
14600
5840
7300
5840
2920
7460
4380
2920
7300
0
4380
1460
0
6488
7300
7300
5840
1460
7300
5840
4380
0
0
0
2920
2920
4380
0
4380
0
5840
7300
7300
5840
0
5840
1460
0
0
0
0
4380
2920
2920
4380
2920
2920
0
7300
5840
7300
7300
5840
0
5840
1460
4380
0
4380
2920
4380
2920
2920
4380
2920
4380
warning: Heap corruption detected at 01628E80

warning: Heap corruption detected at 01624518

warning: Heap corruption detected at 01624518

warning: HEAP[networkthread.exe]:
warning: HEAP: Free Heap block 1624510 modified at 1624520 after it was freed


Program received signal SIGTRAP, Trace/breakpoint trap.
0x7c90120f in ntdll!DbgUiConnectToDbg () from C:\WINDOWS\system32\ntdll.dll

Попробую троллям отрепортить.
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


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


Просмотр профиля
« Ответ #8 : Июнь 26, 2009, 10:57 »

   Вообще странно всё это:

Немогу несогласиться, если троли чего дельного напишут, расскажи ,а то интересно уже))))
Записан
SABROG
Гость
« Ответ #9 : Июнь 26, 2009, 12:00 »

Они где-то на 3-4 моих предыдущих багрепорта вообще ничего не ответили  В замешательстве
Записан
SABROG
Гость
« Ответ #10 : Июль 02, 2009, 16:35 »

В общем такая тема:

Цитировать
Hi Sabrog

Your ThreadHttpDownload object belongs to the main thread. So the slot ThreadHttpDownload::readyRead() above is run in the main thread, while the QNetworkAccessManager and QNetworkReply are running in the thread.

That means the signal readyRead() is queued before delivered to your object. That's why you get the zeroes in size.

And you're calling readAll() from a thread that is not reply's thread. That's a big violation of the QObject guidelines. That's why you're getting the crashes.

This is not a Qt bug.
--
Thiago Macieira - thiago.macieira (AT) nokia.com
  Senior Product Manager - Nokia, Qt Software
     Sandakerveien 116, NO-0402 Oslo, Norway
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


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


Просмотр профиля
« Ответ #11 : Июль 03, 2009, 11:40 »

Пасиба, тоесть на сколько я понимаю moveToThread(this) в конструкторе правельный выход, но вот всётаки интересно почему readReady() работает в основном потоке а не в вторичном, как то это неправельно Непонимающий
Записан
SABROG
Гость
« Ответ #12 : Июль 03, 2009, 15:38 »

Чет я сам понять не могу. Явно же делаем moveToThread на reply, значит должно работать.
Записан
Ymilij
Гость
« Ответ #13 : Март 20, 2010, 07:31 »

Спасибо, эта тема помогла, наконец, разобраться с QNetworkAccessManager.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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