I need to evaluate a lot of prepared xqueries against a stream of XMLs, since QXmlQuery
instances created at startup, copying or moving them to the thread causes an assertion failure. At this point i solve this by creating an instance of QXmlQuery
at each iteration, which leads to an overhead that I would like to avoid with code like:
#include <QFile>
#include <QtXml>
#include <QtXmlPatterns>
#include <QtConcurrent>
QString async_eval(QString doc, QXmlQuery query)
{
QString result;
QXmlQuery second_query(query); // This line will fail with ASSERT (see below)
second_query.setFocus(doc);
second_query.evaluateTo(&result);
return result;
}
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
QFile f("input.xml");
f.open(QIODevice::ReadOnly);
QTextStream stream(&f);
QTextCodec* codec = QTextCodec::codecForName("utf-8");
stream.setCodec(codec);
QString doc = stream.readAll();
QString first_xpath("//price");
QXmlQuery first_q;
first_q.setFocus(doc);
first_q.setQuery(first_xpath);
QString first_res;
std::cout << "First query will be evaluated without warnings" << '\n';
first_q.evaluateTo(&first_res);
std::cout << "first_res = " << first_res.toUtf8().data() << '\n';
std::cout << "Second query will be evaluated with warnings or with debug assert" << '\n';
auto future = QtConcurrent::run(QThreadPool::globalInstance(), async_eval, doc, first_q);
future.waitForFinished();
QString second_res = future.result();
std::cout << "second_res= " << second_res.toUtf8().data() << '\n';
return 0;
}
This code fails with:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x38cb97f930. Receiver '' (of type 'QObject') was created in thread 0x0x17d03fcf5b0", file kernel\qcoreapplication.cpp, line 558 QObject: Cannot create children for a parent that is in a different thread.