QThreadPool:Qt :: QueuedConnection失败

时间:2015-02-10 11:01:05

标签: c++ visual-studio qt threadpool qthread

我有一个C ++ Qt程序,它使用QThreadPool来处理不超过MAX_THREAD_COUNT个线程的文件。我在Qt::QueuedConnection遇到了麻烦。看起来信号丢失了。但是Qt::DirectConnection使用它非常完美。

如果有人能解释发生了什么,我会感激不尽。

UPDATE :此代码在Qt中运行良好,但在Visual Studio 2005中运行不正确。在VS中,它在第一个线程完成后停止(但与Qt::DirectConnection一起使用)

它的外观如下:

Manager.h:

#ifndef MANAGER_H
#define MANAGER_H

#include <QObject>
#include <QThreadPool>
#include <QDebug>
#include "threadbody.h"

class Manager : public QObject
{
    Q_OBJECT   
private:
    QList<QString> processedfiles;
    QList<QString> resultfiles;
    bool ok;
    QString lasterror;
public slots:
    void addToProcessedFiles(const QString& filename);
    void addToResultFiles(const QString& filename);
    void setErrorMessage(const QString& message);
    void startNewThread();
public:
    bool startManager(const QString& firstfile);
    explicit Manager(QObject *parent = 0);
   ~Manager();

};

#endif // MANAGER_H     

ThreadBody.h:

#ifndef THREADBODY_H
#define THREADBODY_H

#include <QTemporaryFile>
#include <QRunnable>
#include <QTextStream>
#define MAX_THREAD_COUNT 4

class ThreadBody : public QObject, public QRunnable
{
    Q_OBJECT
private:
    QString filename;
public:
     ThreadBody(const QString& filename);
     ~ThreadBody();
     void run();
signals:
    void sendResult(const QString& filename);
    void sendFileName(const QString& filename);
    void taskDone();
    void threadError(const QString& message);
};

#endif // THREADBODY_H

Manager.cpp:

Manager::Manager(QObject *parent) :
   QObject(parent)
{
    ok=true;
    QThreadPool::globalInstance()->setMaxThreadCount(MAX_THREAD_COUNT);
}
void Manager::addToProcessedFiles(const QString& filename)
{
    processedfiles.push_back(filename);
    if(QThreadPool::globalInstance()->activeThreadCount()<MAX_THREAD_COUNT)
           startNewThread();
}
void Manager::addToResultFiles(const QString& filename)
{
    resultfiles.push_back(filename);
}
void Manager::setErrorMessage(const QString& message)
{
    ok=false;
    lasterror=message;
}
void Manager::startNewThread()
{
    if(processedfiles.isEmpty())
        return;
    if(!ok)
        return;
    QString filename=processedfiles.takeFirst();
    ThreadBody* task=new ThreadBody(filename);
    connect(task,SIGNAL(taskDone()),this,SLOT(startNewThread()),Qt::QueuedConnection);
    connect(task,SIGNAL(sendResult(const QString&)),this,SLOT(addToResultFiles(const QString&)),Qt::QueuedConnection);
     connect(task,SIGNAL(sendFileName(const QString&)),this,SLOT(addToProcessedFiles(const QString&)),Qt::QueuedConnection);
     connect(task,SIGNAL(threadError(const QString&)),this,SLOT(setErrorMessage(const QString&)),Qt::QueuedConnection);
     qDebug()<<"thread starts";
     QThreadPool::globalInstance()->start(task);
 }

 bool Manager::startManager(const QString& firstfile)
 {
     processedfiles.push_back(firstfile);
     startNewThread();
     QThreadPool::globalInstance()->waitForDone();
     return ok;
 }

 Manager::~Manager(){}

ThreadBody.cpp:

#include "threadbody.h"
#include <QThreadPool>

ThreadBody::ThreadBody(const QString& filename)
{
   this->filename=filename;
}

ThreadBody::~ThreadBody(){}
void ThreadBody::run()
{
    QFile file(filename);
    if(!file.open(QIODevice::ReadOnly))
    {
        QString message=QString("Thread can't open file=%1: %2").arg(filename).arg(file.errorString());
        emit threadError(message);
        emit taskDone();
        return;
    }
    QTextStream in(&file);
    QTemporaryFile newProcessedFile;
    newProcessedFile.setAutoRemove(false);
    if(!newProcessedFile.open())
    {
        QString message="Thread can't open temporary file";
        emit threadError(message);
        emit taskDone();
        return;
    }
    QTextStream out(&newProcessedFile);
    QTemporaryFile resultFile;
    resultFile.setAutoRemove(false);
    if(!resultFile.open())
    {
        QString message="Thread can't open temporary file";
        emit threadError(message);
        emit taskDone();
        return;
    }
    QTextStream resultOut(&resultFile);
    while(!in.atEnd())
    {
        //!---time consuming task---!//
        //example//
        QString currentLine=in.readLine();
        out<<currentLine;
        resultOut<<currentLine;
    }
    resultFile.close();
    newProcessedFile.close();
    file.remove();
    emit sendResult(resultFile.fileName());
    emit sendFileName(newProcessedFile.fileName());
    emit taskDone();
}

main.cpp中:

#include <QCoreApplication>
#include "manager.h"
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   Manager manager;
   QString filename="C:/airtest/ask.cpp";
   manager.startManager(filename);
   return a.exec();
}

0 个答案:

没有答案