I am trying to show a splash screen, and not freeze up the application, while it connects to a database. Normal connections (to MSSQL via ADO) take about 300 msec, and this does not cause the main thread to show "not responding" on windows.
However in the case of (a) a network error or (b) a configuration mistake (invalid SQL server hostname/instance), it takes 60 seconds to time out. This not only makes the application non-responsive, but it's almost impossible to show any error or message when it's going to freeze. I could pop up a message before I start the connection but there's really no solution when the main thread blocks for 60 seconds.
The solution seems to be to move the connection to a background thread. This lead to the following code:
a TThread-class that makes the background connection and some SyncObj like a TEvent used to send a signal back to the main thread.
A loop in the main thread with this code:
BackgroundThread.StartConnecting;
while not BackgroundThread.IsEventSignalled do begin
Application.ProcessMessages; // keep message pump alive.
end;
// continue startup (reports error if db connection failed)
Is this the right way to go? My hesitations involve the following elements of the above solution:
A. I would be calling Application.ProcessMessages, which I consider an extreme code smell.(This might be a permissible exception to this rule)
B. I'm introducing threads into the startup of an application, and I'm worried about introducing bugs.
If anyone has a reference implementation that is known to be free of race conditions, that can do a background connection to ADO, and is known to be a safe approach, that would be really helpful. Otherwise general tips or partial examples are good.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…