First of all, if you have little experience with multithreading, do not start with the VCL classes. Use the OmniThreadLibrary for (among other things) these reasons:
- The abstraction layer is a task, not a thread, a much better way to deal with concurrency.
- You can easily switch between tasks in your thread and schedule them using the thread pool.
- All low-level details, such as flow stop, bidirectional communication, and more, take care of you. You can focus on database materials.
db-thread creates all the database components it needs when creating
This may not be the best way. Usually I only created components when necessary, but did not immediately destroy them. You should definitely open the connection in the thread pool thread and close it only after the thread has been inactive for some time and the pool will delete it. But it is also often recommended to store the cache of transaction objects and operators.
If he receives a command, he takes an action and returns to standby. During this time, the main stream is waiting.
The first part handles fine when using OTL. Nevertheless, there is no expectation of the main thread, this will not bring much advantage over accessing the database directly in the VCL stream in the first place. You need an asynchronous design to make the best use of multiple threads. Consider the standard form of the database browser, which has controls for filtering records. I handle this by (re-) starting the timer every time one of the controls changes. As soon as the user finishes editing timer events, say, after 500 ms, a task is launched that executes an operator that retrieves the data in accordance with the filter criteria. The contents of the grid are cleared, and it is populated only when the task is completed. This may take some time, so the VCL thread does not wait for the task to complete. Instead, the user can even change the filter criteria again, in which case the current task is canceled and a new one is started. OTL gives you an event to complete the task, so asynchronous design is easy to achieve.
What is the best way to get database results from db stream to main stream?
I usually do not use components that support data for multi-threaded db applications, but I use standard controls, which are representations for business objects. In database tasks, I create these objects, put them in lists, and the task completion event transfers the list to the VCL stream.
The main thread and the db thread will never access the request at the same time.
With all the components that load data on demand, you cannot be sure of that. Often, only the first records are extracted from db, and sampling continues after they are consumed. Such components, obviously, should not share threads.