delphi 为什么线程中抛出的异常会破坏我的UI?

5us2dqdw  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(98)

我用TThread发送电子邮件使用Indy。它工作得很好,通过使用一个单独的线程,我避免了我的应用程序UI冻结,而TIdSMTP发送。
问题是,如果在发送过程中发生异常,那么在我的应用程序的UI中就会出现很多奇怪的事情。
例如,我在底部有一个TPanel,用来显示当前状态。我在每个发送步骤中都输入这个面板,例如使用TIdSMTP.OnConnectedTIdSMTP.OnDisconnected这样的事件。
如果在发送过程中出现异常,例如'Socket error',则Panel.Caption 'mix'与以前的面板标题进行新的更新,如下所示:


的数据
此外,我的应用程序的整个UI真的被搞砸了,唯一的方法是关闭应用程序并重新打开它。
看起来我在线程异常处理中做了一些错误的事情,但我在其他过程中使用了很多线程,只有当我使用TIdSMTP时才会出现这个问题。
我需要在TIdSMTP上做些什么来避免这种奇怪的行为吗?

0ve6wy6x

0ve6wy6x1#

永远不要直接从任何辅助线程访问UI组件。这样做通常会导致应用程序代码和Windows GUI系统之间的竞争条件。
在最好的情况下,这将导致像你遇到的视觉故障。但在最坏的情况下,它可能会导致整个Windows UI不稳定甚至崩溃。
因此,访问任何UI元素的正确方法是从应用程序主线程。为了方便地做到这一点, Delphi 提供了两种方法:

  1. Synchronize,它强制你的代码在主线程中执行。当方法在主线程中执行时,它还挂起当前线程的执行。
  2. Queue与Synchronize不同,允许继续执行当前线程。主线程最终将处理所有排队的方法。

相关问题