Hello
I am trying to educate myself in how QT Threads can be used in a Console-based application. On each QThread I'm using QNetworkAccessManager to post SOAP messages and process responses to target systems - this to simulate a monitoring requirement I have.
I have this working, but not as I expected. Rather than the send and receive events being handled on specific threads they all seem to be happening on main thread.
Here's my output (apologies haven't used this forum before, so not sure how to make code standout):
I have an app.exec() in main() [main thread]Thread [0x1550] started running
Main Thread [0x1578] Starting main Application event loop
Thread [0xb74] started running
Thread [0x1578] Send [Data Sent]
Thread [0x1578] Send [Data Sent]
Thread [0x1578] Response [Data back]
Thread [0x1578] Response [Data back]
Thread [0x1578] Send [Data Sent]
Thread [0x1578] Send [Data Sent]
Thread [0x1578] Response [Data back]
Thread [0x1578] Response [Data back]
and an exec() in each created thread
and am using singnals and slots to start the sending, process network response and QTimer to pause before next send...ad infinitum
My suspicion is that I haven't got my signals and slots correctly setup and all events are being managed by the app.exec() and my actual threads are effectively orphaned. Am I missing something?
I'm doing this on Windows Vista and QT 4.6.2 if that makes any difference.
Here's my code:
main() function
The QThread run() function - which I think is the code thatint main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// start two Threads
for (int i=0; i<2; i++) {
opMyThread[i] = new MyThread();
opMyThread[i]->start();
}
if (true) { QMutexLocker Lock(&gmOutput);
std::cout << "Main Thread [" << app.thread()->currentThreadId() << "] Starting main Application event loop" << std::endl;
}
return app.exec();
}
send data function - supposed to be called on the thread, but appears to be called from main threadvoid MyThread::run() {
if (true) { QMutexLocker Lock(&gmOutput);
std::cout << "Thread [" << currentThreadId() << "] started running" << std::endl;
}
connect(this, SIGNAL(readyToSend()), this, SLOT(sendData()));
// kicks off the send/receive event cycle
emit readyToSend();
exec();
}
and finally the slot function to handle network replysvoid MyThread::sendData() {
//had problems with creating QNetworkAccessManager anywhere else (child/parent assertions)
if (opNetManager == 0) {
opNetManager = new QNetworkAccessManager();
connect(opNetManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
}
QByteArray sendData = "<Data>Data Sent</Data>";
if (true) { QMutexLocker Lock(&gmOutput);
std::cout << "Thread [" << currentThreadId() << "] Send [Data Sent]" << std::endl;
}
QNetworkRequest rqst(QUrl("http://localhost:8080/mytarget"));
rqst.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
rqst.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
opNetManager->post(rqst, sendData);
}
Any help or education greatly received.void MyThread::replyFinished(QNetworkReply* reply) {
QByteArray data = reply->readAll();
if (reply->error() == QNetworkReply::NoError) {
QTextStream out(&data);
QString replyString;
replyString.append(data);
if (true) { QMutexLocker Lock(&gmOutput);
std::cout << "Thread [" << currentThreadId() << "] ";
std::cout << "Response [" << replyString.toAscii().constData() << "]" << std::endl;
}
} else {
if (true) { QMutexLocker Lock(&gmOutput);
std::cout << "Thread [" << currentThreadId() << "] ";
std::cout << "Response [" << reply->error() << "]" << std::endl;
std::cout << "Response [" << reply->errorString().toAscii().constData() << "]" << std::endl;
}
}
reply->deleteLater();
// emit the send again with wait
QTimer::singleShot(2000, this, SIGNAL(readyToSend()));
}


Reply With Quote

Bookmarks