Thread and GUI
Thread and GUI
Hi, ALL,
I have a GUI application and there I have a class that doesn't know anything about the GUI.
What I plan to do is to create a function that will run in a thread and fill out some vector with the data. On the GUI side this vector will be read and the data will be populated inside the wxGrid. No writing will be performed from the GUI to this vector.
So now here is my questions:
1. AFAIU I don't need any locking mechanism, because there is only 1 writer, right?
2. What is the best way of checking the vector for a presence of new element? Because I want to update the statusbar with the number of elements when they are added. Or maybe I should clear the vector inside the GUI?
Thank you
I have a GUI application and there I have a class that doesn't know anything about the GUI.
What I plan to do is to create a function that will run in a thread and fill out some vector with the data. On the GUI side this vector will be read and the data will be populated inside the wxGrid. No writing will be performed from the GUI to this vector.
So now here is my questions:
1. AFAIU I don't need any locking mechanism, because there is only 1 writer, right?
2. What is the best way of checking the vector for a presence of new element? Because I want to update the statusbar with the number of elements when they are added. Or maybe I should clear the vector inside the GUI?
Thank you
Re: Thread and GUI
I think the only case where no thread synchronization is needed when there are only read accesses to std::vector and similar. Once you start writing there (e.g., adding or removing its elements), you need to sync.
Re: Thread and GUI
You still need to prevent that reading and writing happens at the same time.1. AFAIU I don't need any locking mechanism, because there is only 1 writer, right?
So the thread produces data which should then be appended to a wxGrid? And afterwards the data in the vector is not needed any more?2. What is the best way of checking the vector for a presence of new element? Because I want to update the statusbar with the number of elements when they are added. Or maybe I should clear the vector inside the GUI?
How many lines of data does the thread produce per second?
There are the usual three options to communicate from a worker thread to the main thread:
1) send an event
2) use a wxMessageQueue() (which you needed to poll in the main thread from a timer or idle event)
3) use Callafter inside the thread
Use the source, Luke!
Re: Thread and GUI
doublemax,
What would people do here without you?
Resolution - don't have hopes too high!
But the execution is fast - basically DB querying.
But as I said the thread function will not know anything about the GUI presence. There is no dependency.
So all 3 options are out.
But maybe I can somehow poll the vector inside the thread, grab the number of elements and send the event?
OTOH, in this case the thread won't have time to do its work as vector will be continuously locked from polling.
And I do want to update this with every single record retrieval.
So what is the best option here?
Thank you.
What would people do here without you?
OK, got it.
Resolution - don't have hopes too high!
Correct.doublemax wrote: ↑Sat Dec 26, 2020 10:58 pmSo the thread produces data which should then be appended to a wxGrid? And afterwards the data in the vector is not needed any more?2. What is the best way of checking the vector for a presence of new element? Because I want to update the statusbar with the number of elements when they are added. Or maybe I should clear the vector inside the GUI?
No idea.
But the execution is fast - basically DB querying.
Yes, I understand all that.
But as I said the thread function will not know anything about the GUI presence. There is no dependency.
So all 3 options are out.
But maybe I can somehow poll the vector inside the thread, grab the number of elements and send the event?
OTOH, in this case the thread won't have time to do its work as vector will be continuously locked from polling.
And I do want to update this with every single record retrieval.
So what is the best option here?
Thank you.
Re: Thread and GUI
So the thread does not create a continuous stream of data, it's just the result of one SQL query?
Unless it takes more than 1-2 seconds, i wouldn't use a worker thread for that.
But if you have to use a thread, you need to establish some kind of communication between worker and gui. I would create a small interface class that's passed to the thread ctor. It would at the very least contain a callback that processes the data, and this would be called with CallAfter().
My second option would be wxMessageQueue, polled from a timer.
Unless it takes more than 1-2 seconds, i wouldn't use a worker thread for that.
But if you have to use a thread, you need to establish some kind of communication between worker and gui. I would create a small interface class that's passed to the thread ctor. It would at the very least contain a callback that processes the data, and this would be called with CallAfter().
My second option would be wxMessageQueue, polled from a timer.
Use the source, Luke!
Re: Thread and GUI
doublemax,
Especially depending on the accessing library - ODBC will process it slower than the native one (extra layer), presence of indexes, network speed, etc.
Just create a thread where you execute a query and when you get all the data - thread dies.
Can you make some pseudo-code for me?
Correct.
Well the query may take some time to work.
Especially depending on the accessing library - ODBC will process it slower than the native one (extra layer), presence of indexes, network speed, etc.
I would prefer it as it seems easier to do.doublemax wrote: ↑Sun Dec 27, 2020 12:19 am But if you have to use a thread, you need to establish some kind of communication between worker and gui. I would create a small interface class that's passed to the thread ctor. It would at the very least contain a callback that processes the data, and this would be called with CallAfter().
Just create a thread where you execute a query and when you get all the data - thread dies.
Can you make some pseudo-code for me?
Thank you.
Re: Thread and GUI
As i had to test if my idea actually worked, i had to make a sample
- Attachments
-
- minimal.cpp
- (9.26 KiB) Downloaded 83 times
Use the source, Luke!
Re: Thread and GUI
doublemax,
I looked at the code and have one question.
As I said I want to set the counter (number of retrieved records on the statusbar after every record retrieval.
So basically it should be like this (for SQLite):
1. Prepare the query.
2. Start the loop
3. Execute sqlite3_step()
4. Update the status bar with the value of 1.
5. Process record 1.
6. Go to step 3.
Now - is it even doable like this?
Maybe I just need to check for the size of the vector somewhere?
Thank you.
I looked at the code and have one question.
As I said I want to set the counter (number of retrieved records on the statusbar after every record retrieval.
So basically it should be like this (for SQLite):
1. Prepare the query.
2. Start the loop
3. Execute sqlite3_step()
4. Update the status bar with the value of 1.
5. Process record 1.
6. Go to step 3.
Now - is it even doable like this?
Maybe I just need to check for the size of the vector somewhere?
Thank you.
Re: Thread and GUI
doublemax,
Sorry for the long delay.
After thinking more about this - what if I have a BLOB field with some images.
So, I think what I need to do is:
Do you think its possible with small modification to that code?
Thank you.
Sorry for the long delay.
After thinking more about this - what if I have a BLOB field with some images.
So, I think what I need to do is:
Code: Select all
1. Start a thread
2. Read a record
3. Send the record to GUI
4. Clean the vector
5. Read second record
Thank you.
Re: Thread and GUI
You just need to redefine DBResultPayload, it can basically be anything.
Use the source, Luke!
Re: Thread and GUI
doublemax,
I understand that.
However, is there a way for a thread to wait until the GUI finishes processing the record?
The 2 reasons I want a thread are:
1. DB communication does not depend on wxWidgets.
2. I should be able to cancel data retrieval.
Thank you.
I understand that.
However, is there a way for a thread to wait until the GUI finishes processing the record?
The 2 reasons I want a thread are:
1. DB communication does not depend on wxWidgets.
2. I should be able to cancel data retrieval.
Thank you.
Re: Thread and GUI
For cancelling you can change the ProcessData() callback to return a value, one value could mean "cancel processing".
For this i would add another method to DBResultConsumerInterface, e.g. bool ReadyToProcess() which the thread uses to check if the main thread is ready to process data. If it's not, just let the thread sleep a little bit.However, is there a way for a thread to wait until the GUI finishes processing the record?
Use the source, Luke!
Re: Thread and GUI
doublemax,
Will this work?
Thank you.
Will this work?
Code: Select all
wxThread::Entry()
{
bool recordReceived = false;
int success = db->PreareQuery();
while( success )
{
success = db->GetRecord();
if( success )
recordReceived = true;
ThreadEvent event();
int rocessed = PostEvent( event );
while( recordReceived && processed )
sleep;
}
}
Re: Thread and GUI
No. First of all i don't think it makes sense to send an event if you haven't received a record (recordReceived = false).
And neither recordReceived nor processed can change their value while this loop is running.
Code: Select all
while( recordReceived && processed )
sleep;
Use the source, Luke!
Re: Thread and GUI
doublemax,
wxQueueEvent ques an event for later processing and therefore does not return any values.
So how do I check if the event is processed?
What do I modify in my pseudo-code?
Thank you.
wxQueueEvent ques an event for later processing and therefore does not return any values.
So how do I check if the event is processed?
What do I modify in my pseudo-code?
Thank you.