【发布时间】:2012-05-21 00:58:56
【问题描述】:
我正在尝试显示启动屏幕,而不是在应用程序连接到数据库时冻结它。正常连接(通过 ADO 到 MSSQL)大约需要 300 毫秒,这不会导致主线程在 Windows 上显示“无响应”。
但是,在 (a) 网络错误或 (b) 配置错误(无效的 SQL Server 主机名/实例)的情况下,超时需要 60 秒。这不仅使应用程序无响应,而且在冻结时几乎不可能显示任何错误或消息。我可以在开始连接之前弹出一条消息,但是当主线程阻塞 60 秒时,确实没有解决方案。
解决方案似乎是将连接移动到后台线程。这导致以下代码:
建立后台连接的 TThread 类和一些 SyncObj(如用于将信号发送回主线程的 TEvent)。
-
主线程中的循环使用此代码:
BackgroundThread.StartConnecting; while not BackgroundThread.IsEventSignalled do begin Application.ProcessMessages; // keep message pump alive. end; // continue startup (reports error if db connection failed)
这是正确的方法吗?我的犹豫涉及上述解决方案的以下要素:
A.我会调用 Application.ProcessMessages,我认为这是一种极端的代码味道。(这可能是该规则允许的例外)
B.我正在将线程引入应用程序的启动中,我担心引入错误。
如果有人有一个已知没有竞争条件的参考实现,它可以与 ADO 进行后台连接,并且已知是一种安全的方法,那将非常有帮助。否则一般提示或部分示例都很好。
【问题讨论】:
-
鉴于正常连接只需要300ms,为什么不改变超时时间(例如1000ms)?
-
如何从后台线程显示启动画面:stackoverflow.com/questions/388506/…
-
此问题是从主 GUI 线程以外的线程显示 UI 的主要用例之一
-
@David,或者如果您不使用数据感知组件,则在工作线程中移动和运行数据库内容。当您执行耗时的查询并且出于某种原因想要使用表单 UI 时,这是可取的(不仅通过一些等待动画阻止用户)。这个模型我已经成功地用于一个工具,它定期轮询数据库,而用户可以使用应用程序的其余部分。但不得不说这里会适合工作线程的形式。
-
要创建一个不依赖于 VCL 且适合线程的表单,请参阅 Creating forms without using VCL 或 Peter Below's Threaded Splash Screen and Modal Dialogs。
标签: multithreading delphi ado