QNetworkAccessManager and QRunnable issue
Hello,
I have the such code architecture. For each request I am creating Worker class, which is QRunnable object and it should be started in a new QThread by QThreadPool.
This Worker has the following code:
Code:
#include "Worker.h"
#include <QString>
Worker::Worker(const WorkerData& data) :
_reader()
_writer(),
_sender()
{
}
void Worker::run()
{
_reader.readFile();
}
void Worker::sendData(const DataToSend& data)
{
_writer.write(data);
_sender.send(data);
}
The Sender header code:
Code:
#include <QObject>
#include <QtNetwork/QNetworkAccessManager>
{
Q_OBJECT
public:
DataSender();
void send(const DataToSend& data);
private:
QNetworkAccessManager _networkMgr;
};
The Sender.cpp code:
Code:
#include <QUrl>
#include <QJsonObject>
#include <QJsonDocument>
#include <QtNetwork/QNetworkReply>
DataSender::DataSender() : _networkMgr()
{
}
void DataSender::send(const DataToSend& data)
{
qDebug() << "\tINFO: [DataSender::send] sending data to endpoint: " << data;
QUrl serviceUrl
= QUrl("http://someUrl.com");
QNetworkRequest request(serviceUrl);
QJsonObject json;
json.insert("data", data.first());
QJsonDocument jsonDoc(json);
request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
request.
setHeader(QNetworkRequest
::ContentLengthHeader,
QByteArray::number(jsonData.
size()));
QNetworkReply *reply = _networkMgr.post(request, jsonData);
}
As you know, the only run() method in QRunnable object is running in a new thread. Based on that, all my QNetworkAccessManager is created in the old thread, because it is not created in run method, am I right?
I am asking about that, because i got the following error:
Quote:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNetworkAccessManager(0xda5a74c), parent's thread is QThread(0xdb14e0), current thread is QThread(0xda579a0)
Do you have any idea why I get this error?
I do not see the cause of the problem...
Re: QNetworkAccessManager and QRunnable issue
Why do you want to create the request in a separate thread at all? It's not needed: https://doc.qt.io/qt-5/qnetworkacces...r.html#details
Re: QNetworkAccessManager and QRunnable issue
Quote:
Originally Posted by
ChristianEhrlicher
..because there will be a lot of requests to my main app and I would like to dispatch them to many threads, thus I use QThreadPool with Workers for each request.
Re: QNetworkAccessManager and QRunnable issue
So did you actually read the link? Then you would see that your idea will not work.
Re: QNetworkAccessManager and QRunnable issue
Quote:
Originally Posted by
ChristianEhrlicher
So did you actually read the link? Then you would see that your idea will not work.
Yes, I saw it. Network manager must be run in the same thread it was created. Based on that I create it in worker, but Worker itself is not in the new thread. In the new thread is Worker::run() method only, am I right?
Re: QNetworkAccessManager and QRunnable issue
I meant this:
"Note: QNetworkAccessManager queues the requests it receives. The number of requests executed in parallel is dependent on the protocol. Currently, for the HTTP protocol on desktop platforms, 6 requests are executed in parallel for one host/port combination."
So there is no real need to create a thread and when then you need to create on QNAM per thread.
Re: QNetworkAccessManager and QRunnable issue
Quote:
Originally Posted by
ChristianEhrlicher
I meant this:
"Note: QNetworkAccessManager queues the requests it receives. The number of requests executed in parallel is dependent on the protocol. Currently, for the HTTP protocol on desktop platforms, 6 requests are executed in parallel for one host/port combination."
So there is no real need to create a thread and when then you need to create on QNAM per thread.
I see, but presence of QNAM is not the main factor to using QThreadPool class. Each request processes files (read/write one file) and based on that the application architecture is better and more flexible.
Re: QNetworkAccessManager and QRunnable issue
Quote:
based on that the application architecture is better and more flexible.
I have a square peg. I do not care if the hole is round. I will make it fit. I just need to use a bigger hammer.
Maybe you should consider threading the file processing after the network requests are complete, and not combine the two and attempt to thread the whole thing.