1

我正在使用 Delphi (7-2010) 并试图找出一种在释放应用程序形式的同时处理异常的好方法。该应用程序有多个由 Application 对象拥有的表单。当用户注销时,我需要释放所有现有表单,以便不维护用户状态,然后为下一个登录用户显示登录对话框。

有时,尝试释放其中一个表单时会发生异常。这将表单留在内存中,但处于未知/不可用状态,因此我无法为下一个用户重新使用表单,也无法将其从内存中删除。因为表单归应用程序所有,所以我不能直接为下一个用户创建表单的新版本,因为它会导致 VCL 出现“名为 MyForm 的组件已存在”错误,我有点反感无论如何都要在内存中拥有旧的表单实例。

我想看看其他人在这种情况下会怎么做。这里有一些想法:

  • 当您遇到这些异常时终止应用程序,因此您一定要擦干净。用户无论如何都要注销,所以他们很可能已经完成了该应用程序。如果需要,可以选择重新启动应用程序。
  • 使表单不属于应用程序,因此您可以创建它们的多个实例,并确保至少隐藏任何不可释放/损坏的表单。
  • 动态生成每个表单的名称,或者将其设置为空白,因此永远不会有重复的名称,也不会出现来自 VCL 的“已经存在”错误。
  • 将应用程序编写得如此出色,以至于在释放对象时永远不会出现异常(不切实际 - 我需要针对意外错误的应急计划)。


我的解决方案是上述最初的想法之一。我在释放表单的循环周围添加了一个 try/except 块,如果出现异常,我将向用户显示错误消息而不引发它,然后调用 ExitProcess(0) 以立即终止应用程序。

4

2 回答 2

6

确实没有很好的方法来处理从析构函数中引发的异常。我不会认为期望它们永远不会被提升是“不切实际的”,因为析构函数不应该做任何可能导致异常的事情。如果除了释放内存或其他清理(释放句柄、关闭连接等)之外,您正在做任何事情,那么您几乎可以肯定做错了什么。

是什么导致了异常,顺便说一句?您是否能够始终如一地重现错误?您最好的做法是修复错误。他们不应该太多。

于 2010-09-03T21:58:19.013 回答
5

大多数情况下,销毁表单时会发生错误,因为仍有一些事件处理程序正在执行并引用已销毁的对象。
这就是为什么在这种情况下TForm.Release被创建用于代替的TForm.Free原因。

来自帮助:
使用 Release 销毁表单并释放其关联的内存。Release 不会销毁表单,直到表单的所有事件处理程序和表单上组件的事件处理程序执行完毕。Release 还保证表单的事件队列中的所有消息都在表单被释放之前得到处理。表单或其子项的任何事件处理程序都应使用 Release 而不是 Free (Delphi) 或 delete (C++)。否则会导致内存访问错误。

于 2010-09-03T22:13:23.660 回答