当数据库连接(可能需要很长时间))运行时,显示启动屏幕 [英] Show a splash screen while a database connection (that might take a long time) runs
问题描述
我正在尝试显示一个启动屏幕,而不是在连接到数据库时冻结应用程序。正常连接(通过ADO到MSSQL)需要大约300毫秒,这不会导致主线程在Windows上显示不响应。
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.
然而,在(a)网络错误或(b)配置错误(无效的SQL Server主机名/实例),需要60秒才能超时。这不仅使应用程序无响应,而且在冻结时几乎不可能显示任何错误或消息。我可以在开始连接之前弹出一条消息,但当主线程阻塞60秒时,实际上没有解决方案。
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:
-
一个TThread类,使后台连接和一些SyncObj像TEvent一样用于发送一条信号返回到主线程。
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。我会调用Application.ProcessMessages,我认为这是一个极端的代码气味(这可能是这个规则允许的例外)
A. I would be calling Application.ProcessMessages, which I consider an extreme code smell.(This might be a permissible exception to this rule)
B。我正在引入一个应用程序的启动,我担心引入错误。
B. I'm introducing threads into the startup of an application, and I'm worried about introducing bugs.
如果有人有一个已知是免费的参考实现条件,可以做一个与ADO的背景连接,并且被认为是一种安全的方法,这将是非常有帮助的。否则一般提示或部分示例是好的。
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.
推荐答案
由于每个线程必须使用自己的ADO连接的已知限制您不能使用在其他线程中创建的连接对象),我可以想到的唯一选项是创建一个将连接到数据库的线程,并且在连接建立或超时达到后,向主线程发出有关事件的信号并关闭/销毁连接。主线程可以同时显示飞溅或进度,等待来自该线程的消息。所以,你消除了错误的密码或不可达的主机的情况。有一个合理的假设,如果第二个线程可以连接,则主线程将能够在之后连接。
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.
这篇关于当数据库连接(可能需要很长时间))运行时,显示启动屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!