You just need a busy flag in the processing code that the thread can check.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.
Thread and GUI
Re: Thread and GUI
Use the source, Luke!
Re: Thread and GUI
double max,
You mean poll inside the thread?
If not - then how?
Thank you.
You mean poll inside the thread?
If not - then how?
Thank you.
Re: Thread and GUI
doublemax,
Can I directly reset the flag from a thread or I will need an event for that?
If its the latter - is there a guarantee that the event processing will done properly?
Thank you.
Can I directly reset the flag from a thread or I will need an event for that?
If its the latter - is there a guarantee that the event processing will done properly?
Thank you.
Re: Thread and GUI
The processing code (in the main thread) is responsible for setting and resetting it.
Use the source, Luke!
Re: Thread and GUI
doublemax,
So it will go like this (IIUC):
In the main thread:
In the thread:
Am I missing something?
Thank you.
So it will go like this (IIUC):
In the main thread:
Code: Select all
wxView::wxView()
[
dataProcessed = false;
}
void OnThreadEvent(wxThreadEvent &event)
{
// process the row
dataProcessed = true;
}
Code: Select all
Entry()
{
int res = GetRecord();
if( !res ) // success
{
wxThreadEvent event( wxEVT_THREAD, WORKING_DATA );
event.SetPayload( row );
wxQueueEvent( m_view, event.Clone() );
while( !m_view->GetDataProcessed )
wxSleep( 500 );
m_view->ResetDataProcessed(); // set the flag to false;
}
}
Thank you.
Re: Thread and GUI
This is now completely different from the code i suggested.
And it doesn't make any sense, the processing code needs to control the busy flag, it's the only one who has that information.
And it doesn't make any sense, the processing code needs to control the busy flag, it's the only one who has that information.
Use the source, Luke!
Re: Thread and GUI
doublemax,
Yes, it is a little different.
Your code is using the simplest case.
As I said before - let's assume I have a following table:
CREATE TABLE photos(id INTEGER PRIMARY KEY, photo BLOB);
and I store some photos in that table like 500jpg or png or bmp or whatever other graphic format files. Or maybe even more than 500 files.
When I load them in the vector all at once I will use a lot of memory.
So I'm trying to read a record from the table and then process it, clean the vector and then read another record.
So yes - it is a little different from what your suggested.
Point is - I don't know what info is stored in the DB and how much. It may be 1 simple record or it may be millions of records of the graphical data.
So - will your code work successfully in both cases? Can I read millions of records of lets say some photoalbum with your code?
Or maybe I am trying to overoptimize all this?
Thank you.
Yes, it is a little different.
Your code is using the simplest case.
As I said before - let's assume I have a following table:
CREATE TABLE photos(id INTEGER PRIMARY KEY, photo BLOB);
and I store some photos in that table like 500jpg or png or bmp or whatever other graphic format files. Or maybe even more than 500 files.
When I load them in the vector all at once I will use a lot of memory.
So I'm trying to read a record from the table and then process it, clean the vector and then read another record.
So yes - it is a little different from what your suggested.
Point is - I don't know what info is stored in the DB and how much. It may be 1 simple record or it may be millions of records of the graphical data.
So - will your code work successfully in both cases? Can I read millions of records of lets say some photoalbum with your code?
Or maybe I am trying to overoptimize all this?
Thank you.
Re: Thread and GUI
The "unique" part of my code was the use of a clearly defined interface to communicate between worker and main thread, and the use of CallAfter. How much data you put into the payload is independent from that and can be adjusted to match your usecase.So - will your code work successfully in both cases? Can I read millions of records of lets say some photoalbum with your code?
For a complete optimization, i'd need to know more. E.g. what do you do with the images in the main thread? If you have to rescale them, or use any kind of image processing, this is of course something that should be done in the worker thread (or even multiple worker threads) and not in the main thread.
Use the source, Luke!
Re: Thread and GUI
doublemax,
I will try to check your code again. If I have more question - I will ask.
Thank you.
I will try to check your code again. If I have more question - I will ask.
Thank you.
Re: Thread and GUI
What you might use here is an Observer Pattern. In java this is a typical method to abstract different GUI elements from each other, so that they are independent of each other but still can communicate via events. Don't know if wxWidgets provides such a mechanism, because AFAIK normally you have to have a window for event processing. Maybe doublemax knows better.
However I have a class written which is open source, which is designed for this kind of thing and in fact I was also using it for a database program among other things.
If you want to take a look at it, you can find it here: https://github.com/skeetor/WinUAE/blob/ ... observer.h
Basically it works like this:
Your database reader is a Dispatcher, your GUI window is a Listener. You pass a pointer of the DB reader to the GUI which shouldn't be a problem because the GUI is allowed to know about about the DB reader. The GUI registers itself as a Listener and implements the handleNotification() function. Whenever the DB updates whatever is you want to signal, then you call notify() and all listeners will get an appropriate event. Since this is a variadic template class, you can pass any kind of parameters you need. You can register as many listeners as you like, i.E. your statusbar could be one listener which just updates the number of records, while you have a grid which shows the records in the GUI. None of them need to poll, because they will get an event when you have one.
However I have a class written which is open source, which is designed for this kind of thing and in fact I was also using it for a database program among other things.
If you want to take a look at it, you can find it here: https://github.com/skeetor/WinUAE/blob/ ... observer.h
Basically it works like this:
Your database reader is a Dispatcher, your GUI window is a Listener. You pass a pointer of the DB reader to the GUI which shouldn't be a problem because the GUI is allowed to know about about the DB reader. The GUI registers itself as a Listener and implements the handleNotification() function. Whenever the DB updates whatever is you want to signal, then you call notify() and all listeners will get an appropriate event. Since this is a variadic template class, you can pass any kind of parameters you need. You can register as many listeners as you like, i.E. your statusbar could be one listener which just updates the number of records, while you have a grid which shows the records in the GUI. None of them need to poll, because they will get an event when you have one.
Re: Thread and GUI
doublemax,
I tried to implement the solution you gave.
Unfortunately, I'm getting an error trying to use wxTheApp or wxGetApp().
If you can get my latest sources and look at dbtableedit.cpp. The code I tried to put is:
I will push the code with the offending line commented out.
Thank you.
I tried to implement the solution you gave.
Unfortunately, I'm getting an error trying to use wxTheApp or wxGetApp().
If you can get my latest sources and look at dbtableedit.cpp. The code I tried to put is:
Code: Select all
m_retriever->SetProcessed( true );
while( m_retriever->GetProcessed() )
wxSleep( 2 );
DataRetriever *retriever = m_retriever;
wxTheApp->CallAfter( [row, retriever]
{
retriever->DisplayData( row );
} );
Thank you.
Re: Thread and GUI
Which error? As it always takes a long time getting the project to build for me, i can't test this easily.
Use the source, Luke!
Re: Thread and GUI
doublemax,
Error is "Undeclared identifier".
Hopefully you will be able to figure it out by the code (without building).
Thank you.
Error is "Undeclared identifier".
Hopefully you will be able to figure it out by the code (without building).
Thank you.
Re: Thread and GUI
wxTheApp is a global variable, it should be accessible from anywhere. Try including "wx/wx.h".
Use the source, Luke!