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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Прервать парсинг QDomDocument::setContent в отдельном потоке  (Прочитано 6953 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Август 05, 2014, 08:10 »

Привет. Столкнулся с такой задачей. У меня в потоке открывается файл QFile, его содержимое передаю в QDomDocument::setContent(&file). Файл порядка 12 МБайт, парсится долго, иногда нужно прервать его парсинг. Но я так и не понял, как сделать корректно досрочное завершение потока.

Код:
#include <QThread>
#include <QDomDocument>
#include <QDomElement>

#include "railcore_global.h"

class RAILCORESHARED_EXPORT CDocReaderThread : public QThread
{
    Q_OBJECT

    QDomDocument    *   fdocument;
    QString             ffileName;

    Q_DISABLE_COPY(CDocReaderThread)

public:

    explicit CDocReaderThread(QDomDocument * document, const QString & fileName, QObject *parent = 0);
    void        run();

signals:

    void    done();
    void    error();

public slots:

};

Код:
#include <QFile>
#include "cdocreaderthread.h"

CDocReaderThread::CDocReaderThread(QDomDocument *document, const QString &fileName, QObject *parent) :
    QThread(parent),fdocument(document),ffileName(fileName)
{
}

void CDocReaderThread::run()
{
    if(!fdocument || ffileName.isEmpty())
    {
        emit    error();
    }
    else
    {
        QFile   file(ffileName);
        if(!file.open(QIODevice::ReadOnly))
        {
            emit    error();
            return;
        }

        QString errorMsg = "Unknown error";
        int     errorLine = -1;
        int     errorColumn = -1;

        if(!fdocument->setContent(&file,true,&errorMsg,&errorLine,&errorColumn))
        {
            qDebug("ArmDocument parse error: line %d, column %d: %s",errorLine,errorColumn,qPrintable(errorMsg));
            emit    error();
            return;
        }

        emit    done();
    }

Если делать так:
Код:
void abortRead()
{
reader->quit();
reader->wait();
}

То поток завершится после полного парсинга документа. и возвращается сигнал done().

Если пользоваться reader->terminate() то прога тупо виснет... Подскажите есть ли способ как то в процессе парсинга документа сделать завершение потока?
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Август 05, 2014, 18:19 »

Попробуй использовать QtConcurrent. Для прерывания там есть метод cancel(). Проверь, может заработает.
Записан

ArchLinux x86_64 / Win10 64 bit
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #2 : Август 05, 2014, 19:25 »

Попробуй использовать QtConcurrent. Для прерывания там есть метод cancel(). Проверь, может заработает.
cancel() не прерывает единичную функцию, чуда не происходит. Это действует если применять map() на массиве данных.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Август 05, 2014, 19:37 »

Я бы попробовал унаследoваться от QFile и там ловить флажок отмены возвращая ошибку чтения.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #4 : Август 05, 2014, 19:40 »

Цитировать
cancel() не прерывает единичную функцию, чуда не происходит. Это действует если применять map() на массиве данных.

А, ну тогда читать файл частями и на каждой итерации проверять некий флажок. И если он установлен в "break" - то не запускать следующую итерацию - а просто завершить (хотя не уверен что можно парсить DOM-документ по-частям).
Записан

ArchLinux x86_64 / Win10 64 bit
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #5 : Август 05, 2014, 21:25 »

Да в том то и дело, что операция парсинга "атомарная" - даешь указатель на файл, и получаешь уже результат. Грустный
Оставил пока эту затею.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #6 : Август 05, 2014, 21:49 »

Да в том то и дело, что операция парсинга "атомарная" - даешь указатель на файл, и получаешь уже результат. Грустный
Оставил пока эту затею.
В этот процесс можно попытаться вклиниться)

Я бы попробовал унаследoваться от QFile и там ловить флажок отмены возвращая ошибку чтения.

Лучше отнаследоваться не от QFile, а от QXmlInputSource. Покурить там метод next.. Думаю, он его при парсинге дёргает, но это только предположение..
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #7 : Август 12, 2014, 15:46 »

я уже тоже об этом подумал, но пока забил.. есть куда более важные вещи.. )
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #8 : Август 12, 2014, 16:42 »

Для больших документов лучше использовать QXmlStreamReader. Это поточный парсер и ты всегда можешь прервать разбор.
Записан

Гугль в помощь
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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