Infinite loop and signal deluge
-
wrote on 5 May 2011, 07:34 last edited by
[quote author="Andre" date="1304344127"]I would simply make sure that you don't emit your signal if it should not emit.[/quote]In fact I always want to emit this signal. I "rephrased" my question in the first post.
-
wrote on 5 May 2011, 07:56 last edited by
maybe this?
@while ( !stop ){
bool finished = false;
finished = someLongProcessing(*textResult); // if you finshed parsing your text return true
if(finished)
emit displayText(textResult);
}@ -
wrote on 5 May 2011, 09:12 last edited by
I don't get it. With your finished boolean you just turn someLongProcessing() into a blocking call. But it is already blocking.
-
wrote on 5 May 2011, 09:23 last edited by
Sorry forgot the stop = true; line.
@while ( !stop ){
bool finished = false;
finished = someLongProcessing(*textResult); // if you finshed parsing your text return true
if(finished){
emit displayText(textResult);
stop = true;
}
}@ -
wrote on 5 May 2011, 09:30 last edited by
This will break the loop. I don't want to break the loop when someLongProcessing() returns true. You obviously did not understood my problem.
-
wrote on 5 May 2011, 09:53 last edited by
It is generally only useful to update a text if it has actually changed, so assuming that some successive calls may produce the same text result:
@QString previousText;
while (true) {
QString text = someLongProcessing();
if (previousText != text) {
previousText = text;
emit displayText(text);
}
}@ -
wrote on 5 May 2011, 11:44 last edited by
I'm sorry but successive calls wont produce the same result.
There's nothing to do with the event queue? -
wrote on 5 May 2011, 11:52 last edited by
QApplication::processEvents() helps?
-
wrote on 5 May 2011, 11:59 last edited by
Hi neFast,
is this loop executed in a thread?
If yes, processEvents will never help. -
wrote on 5 May 2011, 12:04 last edited by
Yes it is in a thread. What do you suggest?
-
wrote on 5 May 2011, 12:16 last edited by
From that thread you have no influence on the main thread directly by calling processEvents etc. If you fill up the queue of one thread by another one, you have to think, whether it is the correct way for doing so.
Perhaps you should change the logic to something like this:
thread --> setText on intermediatObject --> emit signal
intermediatObject is a thread save object, which stores the last text and stores, whether the text was already read. If a text is set, it emits the signal, if after the last read there came no new text.
But that changes the logic completely...
-
wrote on 5 May 2011, 12:21 last edited by
Another consideration is that the text might change quickly enough for the user not even to notice it. It would probably make sense to not let the longProcessThingy() control the text the user sees unless there's an error of sorts. The current approach seems indeed too naive for successful operation.
-
wrote on 26 May 2011, 14:09 last edited by
Sorry to bump this thread, but are there any best practice that I could find to solve my problem?
- EDIT: I just found about Qt::BlockingQueuedConnection, could this be a good idea?
-
wrote on 26 May 2011, 14:35 last edited by
If your thread can wait, sure, try that.
-
wrote on 26 May 2011, 14:37 last edited by
I'm affraid it will affect performances. I'll try that and report here.
-
wrote on 26 May 2011, 14:40 last edited by
It will slow down your thread somewhat, yes. If the thread cannot wait, you should probably go for Gerolf's solution or something like it.
-
wrote on 26 May 2011, 14:44 last edited by
[quote author="Franzk" date="1306420801"]Gerolf's solution or something like it.[/quote] Any details on this?
Gerolf method could work with text (because it does not always change), but I also emit pointer to images. And after each loop the image changes, so I need to either:- wait for the event to be processed (in a performance friendly fashion)
- trash events if too many of them are fired
I cannot use this "emit only if required" idea, because I can not decide if it's required based on the content of the image.
-
wrote on 26 May 2011, 14:51 last edited by
Hmno, that was Andre's suggestion. Read "Gerolf's suggestion":https://developer.qt.nokia.com/forums/viewreply/33804/ again.
-
wrote on 26 May 2011, 15:08 last edited by
Yes your right, I will end up doing something like this if I don't find anything simpler.
I'm now considering this:
adding a new emit processEventsInMain() in the loop,
and connect this signal in a blocking way to a slot of my main thread that will just consist in a processEvents() call. -
wrote on 26 May 2011, 17:49 last edited by
Nonono, bad idea. the queued signal will be called if the main thread enters the event loop, so that will not solve the problem, you will get others. Opening the event loop is not a good idea, you get asynchronous behavior where you don't expect it.
What is wrong with the intermediate object? That also works with any kind of data. Simple but powerfull pattern:
The object stores the current data (or perhaps the current and the last). It has a member bNewDataEmitted. If this value is false, a dataChanged signal is emitted and the value is set to true. On each consecutive call of set data, no signal is emitted until the value goes to false.
Each getData sets the value to false, so a dataChanged can be emitted on next setData.