Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show a splash screen while a database connection (that might take a long time) runs

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:

  1. a TThread-class that makes the background connection and some SyncObj like a TEvent used to send a signal back to the main thread.

  2. 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.

like image 816
Warren P Avatar asked May 21 '12 00:05

Warren P


1 Answers

Because of the known limitation that every thread must use it's own ADO connection (ie you cannot use a connection object created in other thread), the only option I can think of is create a thread that will make a connection to database, and, after the connection is established or timeout is reached, signal the main thread about the event and close/destroy the connection. The main thread can in the meantime display splash or progress, waiting for a message from that thread. So, you eliminate the case with wrong password or unreachable host. There is a reasonable assumption, that, if the second thread could connect, the main thread would be able to connect right after.

like image 176
Silver Avatar answered Oct 18 '22 16:10

Silver