【问题标题】:Show a splash screen while a database connection (that might take a long time) runs在数据库连接(可能需要很长时间)运行时显示启动屏幕
【发布时间】:2012-05-21 00:58:56
【问题描述】:

我正在尝试显示启动屏幕,而不是在应用程序连接到数据库时冻结它。正常连接(通过 ADO 到 MSSQL)大约需要 300 毫秒,这不会导致主线程在 Windows 上显示“无响应”。

但是,在 (a) 网络错误或 (b) 配置错误(无效的 SQL Server 主机名/实例)的情况下,超时需要 60 秒。这不仅使应用程序无响应,而且在冻结时几乎不可能显示任何错误或消息。我可以在开始连接之前弹出一条消息,但是当主线程阻塞 60 秒时,确实没有解决方案。

解决方案似乎是将连接移动到后台线程。这导致以下代码:

  1. 建立后台连接的 TThread 类和一些 SyncObj(如用于将信号发送回主线程的 TEvent)。

  2. 主线程中的循环使用此代码:

    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 VCLPeter Below's Threaded Splash Screen and Modal Dialogs

标签: multithreading delphi ado


【解决方案1】:

由于每个线程必须使用它自己的 ADO 连接的已知限制(即您不能使用在其他线程中创建的连接对象),我能想到的唯一选择是创建一个与数据库建立连接的线程,并且,在建立连接或达到超时后,向主线程发出有关事件的信号并关闭/销毁连接。主线程可以同时显示启动画面或进度,等待来自该线程的消息。因此,您消除了密码错误或主机无法访问的情况。有一个合理的假设,如果第二个线程可以连接,那么主线程就可以立即连接。

【讨论】:

  • +1,同意,但是您需要将所有数据库操作移动到该线程中,因为您无法将连接对象从您的工作线程传递到主线程。并且有必要将它们放在主线程中,例如如果您使用的是数据感知组件。
  • 他是说你只打开然后关闭那个连接。因此,您只是将初始连接作为应用程序的“错误检查”功能来处理。您仍然需要在主线程中重新执行连接逻辑。
  • @Warren,如果您只想验证是否可以连接并稍后在主线程中使用相同的连接设置重新连接,那么您可以使用我删除的代码(现在真的已删除)回答。
【解决方案2】:

线程间通信有多种方法。我通常使用 Window 的消息。首先,我在表单中定义客户消息和消息处理程序。然后当我需要通知主要 自定义线程中的线程,我使用 PostMessage 函数发送通知。

小教程here.

您也可以使用库进行线程处理,例如OmniThreadLibrary

【讨论】:

  • 我知道。但是我特别想知道阻止我的应用程序启动 - 我该怎么做 - 我自己的消息泵循环(调用 application.process 消息)或其他什么?
  • 我最终在线程中显示了启动画面。请参阅我对问题的评论中的链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 2014-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多