Subject | Re: [IBO] Dealing with complex queries |
---|---|
Author | Daniel Albuschat |
Post date | 2008-07-11T11:35:49Z |
2008/7/8 Robert martin <rob@...>:
solving this.
The main problem here is that a Firebird-connection can only be used
from ONE thread. When using visual components, this thread is the same
as the GUI/main-thread. When not using visual components, but creating
TIB_Connection and friends in your code, it's relatively easy to put
_all_ database-access into a thread. That is maybe the best solution.
Since Delphi is full of event-driven mechanisms, you can turn your
database-access into asynchronous processes, too.
An "execute" will send the statement to the database-thread, where it
is processed. "execute" will immediately return and leave the main
program flow unoccupied. Then, when the database-thread has finished
executing, a "OnExecFinished" event occurs.
However, this mechanism is quite some effort to implement and
difficult to debug, but it is _definitely_ the very best solution.
Asynchronous processing makes your application responsive and
scalable, not leaving the user in the believe your app crashed hard or
something. It all became worse when XP introduced indicators that the
application "might have crashed", which got even worse in Vista.
Customers often call because they think the application has crashed,
but it actually only executed a very complex statement (which can be
built by the user and hence can't always be optimized).
I have, however, created a different solution. I'm working on a huge
codebase (roughly 300.000 lines of code full of IBO) and it was simply
not applicable to redesign it to use a database-thread. So I've come
up with a way to "move over" the GUI-processing to a different thread.
The new GUI-thread does nothing but display an animation (in avi
format) and ignores all input events, using pure win32-API and no VCL.
This is very hacky and really not desireable, but was the easiest
solution in my situation and even works reliably. If anyone is
interested in it (and has good reasons not to re-design their app),
I'll be glad to share the code.
Regards,
Daniel Albuschat
--
eat(this); // delicious suicide
> My understanding is that threads should not have direct access to visualI'd like to clarify on this one, since I've put quite some effort in
> components (otherwise you get strange / random crashes). You could
> synchronise the calls to the main thread but I suspect it might also
> cause problems (note that MS used to use this system for its progress
> indicators and stopped doing it).
solving this.
The main problem here is that a Firebird-connection can only be used
from ONE thread. When using visual components, this thread is the same
as the GUI/main-thread. When not using visual components, but creating
TIB_Connection and friends in your code, it's relatively easy to put
_all_ database-access into a thread. That is maybe the best solution.
Since Delphi is full of event-driven mechanisms, you can turn your
database-access into asynchronous processes, too.
An "execute" will send the statement to the database-thread, where it
is processed. "execute" will immediately return and leave the main
program flow unoccupied. Then, when the database-thread has finished
executing, a "OnExecFinished" event occurs.
However, this mechanism is quite some effort to implement and
difficult to debug, but it is _definitely_ the very best solution.
Asynchronous processing makes your application responsive and
scalable, not leaving the user in the believe your app crashed hard or
something. It all became worse when XP introduced indicators that the
application "might have crashed", which got even worse in Vista.
Customers often call because they think the application has crashed,
but it actually only executed a very complex statement (which can be
built by the user and hence can't always be optimized).
I have, however, created a different solution. I'm working on a huge
codebase (roughly 300.000 lines of code full of IBO) and it was simply
not applicable to redesign it to use a database-thread. So I've come
up with a way to "move over" the GUI-processing to a different thread.
The new GUI-thread does nothing but display an animation (in avi
format) and ignores all input events, using pure win32-API and no VCL.
This is very hacky and really not desireable, but was the easiest
solution in my situation and even works reliably. If anyone is
interested in it (and has good reasons not to re-design their app),
I'll be glad to share the code.
Regards,
Daniel Albuschat
--
eat(this); // delicious suicide