Solved Error on QEventLoop::exec() under windows (works well under linux)
-
Hi,
I have a software with this kind of code in a function (or in several functions) :QNetworkReply * reponse = m_pNetManager->post(requete,postData.toString(QUrl::FullyEncoded).toUtf8()); QEventLoop loop; connect(reponse, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(); QString strReply = (QString)reponse->readAll();
this software work well under linux but on windows,when we process a lot of(or severals) requests the software crashes on loop.exec():
on the stack there is :
user32!getthreaddesktop
user32!charprevW
user32!dispatchmessageW
QEventdispatcherwin32::processevents
QEventLoop::processEvents
QEventloop::execthis eventloop and loop.exec() is in a function that is executed in a secondary thread.
I haven't any problem with this software under linux even with a lot of(or severals) requests.
Can someone help me to solve the problem ? -
Hi,
I use Qt5.6.2 and mingw-w64 (32 and 64 bits) -
HI, it seems to bugs randomly because my last test with the same requests is ok.....
-
honestly I do not like that code snippet one bit... try with:
QNetworkReply * reponse = m_pNetManager->post(requete,postData.toString(QUrl::FullyEncoded).toUtf8()); connect(reponse,&QNetworkReply::finished,reponse,[reponse](){ QString strReply = QString::fromUtf8(reponse->readAll()); qDebug() << strReply; }); connect(reponse,&QNetworkReply::finished,reponse,&QNetworkReply::deleteLater);
(QString)reponse->readAll();
is ambiguous as you cant see what encoding you are using without checking the docs it also looks like a C-cast (even though it's not) which usually frowned uppon in C++ -
@VRonin Thanks for your response.
first I don't delete reponse and I have several part of code like this so it is perhaps the problem.(you have put a deletelater so it is better)
second I have a question about your code: I have about ten lines following reponse->readAll() and above local variables so should I put these lines in the lambda function and pass the variables as parameters to the lambda like reponse ? -
Hi,
You could also try it with the following code snippet:
connect (m_pNetManager, &QNetworkAccessManager::finished, &loop, [&](QNetworkReply* reply) { loop.quit(); qDebug() << reply->error(); }); loop.exec();
So instead of connecting to your QNetworkReply object, connect to the QNetworkManager instead. I'm using the above snippet in my software and it works well (Qt 5.7.0 & Qt 5.8.0 both MSVC14 and OS x Clang 64).
Also note that you need to disconnect the slot in my proposed solution after you got the reply. You can use an RAII construction for this as the
connect ()
function will return a QMetaObject::Connection instance.Please let me know if this works for you.
-
so should I put these lines in the lambda function and pass the variables as parameters to the lambda like reponse
It depends a lot on:- what those variables are?
- what is their life-cycle?
- what do you do with them?
-
@VRonin I have local variables so it is not the problem but I have too two member variables and one that is an object on an sqlite database and I insert /update with it. On another project where I have used lambda functions (but a microsoft project with visual studio 2013) I had problems with such complex member variables in lambda and I must pass &this in the arguments of the lambda but perhaps lambda work better with mingw-w64 4.9.2, I will try.
another question : don't you use QEventLoop and loop.exec() because of the lambda function ? so it will solve my problem with loop.exec , so I try now to implement your solution....I come back to let you know if it works well and if it solves my problem.... -
QEventLoop::exec forces an asynchronous process as QNetworkAccessManager::post to be synchronous. Especially with a large number of posts this is forcing an unnatural behaviour
-
@VRonin thanks a lot. I have made two tests and it seems to work well.
I use "this" as parameter in the lambda function to acces my member database variable and another variable.
I will replace everywhere in the software the loop.exec() by a lambda function because I feel the software is faster now!!!! (and I will replace in another software where there are such loop.exec()). -
@VRonin, it works with mingw 4.9.2 under windows but is it ok too on mac os with clang and with g++ on linux ?
-
@stephane78 Yes, it should. Did you test?
-
@jsulm I am testing on windows (with mingw 4.9.2,Qt5.6.2) and I will replace evrywhere in the software the loop.exec() by a lambda and test again. if it works well I will replace them too in another existing software.
I have not yet tested on mac os and on linux. I suppose the clang and g++ version must support c++11 -
@stephane78 said in Error on QEventLoop::exec() under windows (works well under linux):
clang and g++ version must support c++11
yes they do
-
@VSRonin, @jsulm I have done the change in the two part of my function where I have an event loop and now it doesn't crash anymore (even with a lot of requests) and it works.