This code is executing in a thread
Now, it does not. Your code is:
Synchronize(OpenTable);
This explicitly means OpenTable
procedure is executed within Main VCL thread and outside of your background auxillary TOpenThread
.
More details on Synchronize
that you may try to learn from are at https://stackoverflow.com/a/44162039/976391
All in all, there is just no simple solutions to complex problems.
If you want to offload DB interactions into a separate thread, you would have to make that thread exclusive owner and user of all DB components starting from the very DB connection and up to every transaction and every query.
Then you would have to make means to ASYNCHRONOUSLY post data requests from Main VCL Thread to the DB helper thread, and ASYNCHRONOUSLY receive data packets from it. Something like OmniThreadLibrary does with data streams - read their tutorials to get a gist of internal program structure when using multithreading.
You may TRY to modify your application to the following rules of thumb.
It would not be the fastest multithreading, but maybe the easiest.
all database components work is exclusively done inside TOpenThread.Execute
context and those components are local members variables to the TOpenThread
class. The connection-disconnection made only within TOpenThread.Execute
; TOpenThread.Execute
waits for the commands from the main thread in the almost infinite (until the thread gets terminated) and throttled loop.
specific database requests are made as anonymous procedures
and are added to some TThreadedQueue<T>
public member of TOpenThread
object. The loop inside .Execute
tries to fetch the action from that queue and execute it, if any exists, or throttle (Yield()
) if the queue was empty. Neither Synchronize
nor Queue
wrappers are allowed around database operations. Main VCL thread only posts the requests, but NEVER waits for them to be actually executed.
those anonymous procedures after being executed do pass the database results back into main thread. Like http://www.uweraabe.de/Blog/2011/01/30/synchronize-and-queue-with-parameters/ or like Sending data from TThread to main VCL Thread or by any other back-into-main-thread way.
TOpenThread.Execute
only exits the loop if the Terminated
flag is set and the queue is empty. If Terminated
is set then immediate exit would loose the actions still waiting on queue unprocessed.
Seems boring and tedious but easy? Not at all, add there that you would have to intercept exceptions and process all the errors in the async way - and you would "loose any hope entering this realm".
PS. and last but not least, about "This code is executing in a thread, and keeps doing it while the main thread gets stucked" supposition, frankly, I guess that you are wrong here and i think that BOTH your threads are stuck by one another.
Without fully understanding how thread-to-thread locking is designed to work in this specific component, carpet-bombing code with calls to Synchronize
and other inter-thread locking tools, you have quite a chance to just chase them all your threads into the state of mutual lock, deadlock. See http://stackoverflow.com/questions/34512/