how to replace loop.exec() ? (not by a lambda)
-
Hi,I want to replace the loop.exec() in that code (not by a lambda) :
QNetworkReply * reponse = netmanager->post(requete,multiPart); QEventLoop loop; connect(reponse, SIGNAL(finished()), &loop, SLOT(quit())) ; loop.exec();
this code is in a slot of a secondary thread.
any good idea? -
Why do you need a loop and a thread at all? QNetworkAccessManager requests are asynchronous. You don't need to start them in a separate thread, they already run in worker thread.
-
@Chris-Kawa there is more code in the function and other variables that I need after the loop.exec().if I do only a connect with another slot without the loop,,as signal finished() hasn't any parameters I cannot pass my variables as parameter.the loop.exec() allow to stay in the same function with the same variables
it is in a thread because it is an application where I have several threads and I need a thread specially to upload the files. -
I'm just saying that you've got a thread that starts another thread and then just sits and waits. Seems this could avoided but I don't know your code, so there might be more to it.
Anyway...signal finished() hasn't any parameters I cannot pass my variables as parameter
You can use a lambda and capture your variables to tag along i.e.
SomeVariable foo; QNetworkReply * response = netmanager->post(requete,multiPart); connect(response, &QNetworkReply::finished, [foo](){ doStuff(foo); }) ;
Then you don't need a loop.
-
@Chris-Kawa the problem of the lambda,it is does not support well when they are thing like QFile * access ,database access with QReadwritelock,there are a lot of problems....I have already done lambda in other parts of the software but here it doesn't work....
my problem with the loop.exec() is that under windows the loop.exec() take windows resources,and when there are a lot of upload request fast simultaneaously, it crashes (in other software I haven't any problems with the loop.exec() but with these software I have sometimes crashes) -
I don't think it's a good idea to keep file handles open or locks locked waiting on a reply when you have a lot of requests in flight. I would expect exactly the problems you're mentioning with such setup.
There's no way around it - for a slot of a queued connection to be called there needs to be an active event loop in the thread the receiver lives in. I would redesign the approach around that idea: get resources needed to make a request, make a request and don't wait for it, release the resources. QNAM will call you back at some point and you can react there, reacquire the resources if needed, but don't block them. Having a thread and an event loop for every connection (that runs in yet another thread) is just very wasteful.
-
@Chris-Kawa 1)when you upload one file ,you must open it to read it.so you must close it when it is finished(in the response) so either in the lambda or after the loop.exec(),and in the lambda I have problems here for this file....
2) the other Qfile * is for a trace but I didn't already test it(after the loop.exec() or in the lambda...)
3)the database access with a QReadWriteLOck is after the loop.exec() or in the lambda (but it doesn't work in the lambda) and is needed after the file is uploaded because in the response of the upload I get some information that I put in my database
I find that compilers don't support very well lambdas,here I have problems with mingw-w64 4.9.2 and 5.3.0 (x86_64) and in another project (microsoft with vs2013) I had problems with lambdas too..... -
and in the lambda I have problems here for this file....
What kind of problems? Maybe we can help with that. Closing a file in a lambda should not be anything special.
the other Qfile * is for a trace
Do you mean something like a log? Maybe you don't need to keep it open the whole time. Just open it when you need to write to it?
the database access with a QReadWriteLOck is after the loop.exec() or in the lambda (but it doesn't work in the lambda)
Lambda is not magic. It's just an object with a function. If you don't want a lambda use a regular function and store the variables in some class member, but that's no different. You just need to make sure the lambda is executed in the right thread (you can specify the context object parameter to the connect for that).
I find that compilers don't support very well lambdas
What are you talking about? They've been around for over 6 years now. All major compilers do support them and have for years, even the old ones. I'm using them on daily basis even in VS2012. Sorry, but without a concrete example that sounds like a made up excuse.
-
@Chris-Kawa when you do debug with gdb,there are sometimes some problems that appears, (for example in the lambda or for other things) that you haven't when you run normally the software.it is perhaps because of that that I some problems with the file and other problems, because I did debug with gdb......(I use mingw-w64)
-
OK my problem is solved.it seems there wasn't any problem with my loop.exec() (in the example that I have where it crashes)....
so I have keeped my loop.exec().
there were only sql problems (specially because I had done:....where locapath='path'
and I have replaced it with
where localpath=\"path\"
and When there were two conditions I have putted () :
where () and ()
because I didn't putted it before....now it works perfectly....I didn't find such things by doing debugging with gdb...
-
@Chris Kawa, Ok I have made it by doing a lambda,by putting outside of the lambda all the QFile,database,QMutex,QreadWriteLock...so I have only my reponse to the upload request inside the lamdba now. But it doesn't work at all now.the lambda is in a Qobject moved to thread and in debug mode it fails on the QThread.exec() and QeventLoop exec of the thread....here is my new code :
QNetworkReply * reponse = netmanager->post(requete,multiPart); multiPart->setParent(reponse); connect(reponse,&QNetworkReply::finished,reponse,[this,nomsymb,&idFichier,&du,&dup,&sha1,reponse](){ QString strReply = QString::fromUtf8(reponse->readAll()); QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8()); QJsonObject jsonObject = jsonResponse.object(); long idFichier = (long)jsonObject["fileId"].toDouble(); QString nom = jsonObject["fileName"].toString(); du = QDateTime::fromString(jsonObject["dateUpload"].toString(),"yyyy-MM-dd HH:mm:ss"); if(this->flag) dup = QDateTime::fromString(jsonObject["updated_at"].toString(),"yyyy-MM-dd HH:mm:ss"); sha1=jsonObject["checksum"].toString(); int code=jsonObject["code"].toInt(); if (idFichier==0) { if (code==114) emit uploaderror(code,nomsymb); } });
all thsi code is in a QObject that is in a secondary thread because my app has several secondaries threads,so it is a QObject moved to thread thanks to movetothread....
it works with a loop.exec() but I have sometimes errors on the loop.exec when uploading fast a lot of files.now with the lambda it doesn't work at all.
any idea with the lambda Chris? -
@Chris Kawa,when using a loop.exec() and not a lambda the errors that I have sometimes are only on windows I think, not on linux because I had such errors on another request under windows but not under linux and I replaced it by a lambda but it was not the upload request...
-
I think I will try with another version of Qt.now I was using Qt5.6.2.
I will try with Qt5.9.0