2010-09-03 72 views
1

我正在使用Delphi(7-2010)并试图找出处理异常并释放应用程序形式的好方法。该应用程序有几个由Application对象拥有的表单。当用户注销时,我需要释放所有现有表单,以便不保留用户状态,然后显示登录对话框以供登录的下一个用户使用。德尔福:当一个表单在注销应用程序时无法释放时该怎么办

偶尔,尝试释放其中一个表格。这会将表单留在内存中,但处于未知/不可用状态,因此我无法重新使用下一个用户的表单,而且我也无法从内存中清除它。由于表单由应用程序拥有,我无法直接为下一个用户创建表单的新版本,因为它会导致VCL中出现“名为MyForm的组件已存在”错误,而且我有点厌恶无论如何在内存中都有旧的表单实例。

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

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


我的解决方案是上面的最初想法之一。我在循环中添加了一个try/except块来释放窗体,如果有异常,我会向用户显示错误消息而不提高它,然后调用ExitProcess(0)立即终止应用程序。

回答

6

真的没有好方法来处理从析构函数中引发的异常。我不会称它为“不现实的”,期望它们永远不会被提出,因为析构函数不应该做任何可能导致异常的事情。如果你除了释放内存或其他清理(释放句柄,关闭连接等)之外的任何事情,你几乎肯定会做错事情。

什么导致例外,BTW?你能否一致地重现错误?你的最佳行动是纠正错误。不应该有太多。

+0

这些错误代表许多事情。过去的例子是试图保存其状态并因任何原因失败的第三方组件,例外情况下断开连接/数据集,未知原因的AV等。这并不是说这些错误是众多或常见的,但我想成为积极主动并使应用程序能够智能地行动,即使在出现新的/意外错误的罕见情况下也是如此。 – Anagoge 2010-09-03 22:28:49

+1

@Anagoge:好的。那么,如果用户在任何时候注销,那么我会在转储异常日志并将其发送给您之后终止该应用程序。 (如果您没有办法做到这一点,请查看MadExcept或EurekaLog。它们对于跟踪部署代码中的错误非常重要,这是实际让调试器连接到用户应用程序的下一个最好的事情。) – 2010-09-03 23:06:51

4

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

来自帮助:
使用发布销毁表单并释放其关联的内存。 在窗体上的组件的窗体和事件处理程序的所有事件处理程序都已完成执行之前,发布不会破坏窗体。发布还可以确保表单的事件队列中的所有消息都在表单发布之前得到处理。表单或其子项的任何事件处理程序应该使用Release而不是Free(Delphi)或删除(C++)。如果不这样做可能会导致内存访问错误。

相关问题