1

私は Delphi (7-2010) を使用しており、アプリケーションのフォームを解放しながら例外を処理する良い方法を見つけようとしています。アプリケーションには、Application オブジェクトが所有するいくつかのフォームがあります。ユーザーがログアウトしたら、既存のフォームをすべて解放して、ユーザーの状態が維持されないようにし、次にログインするユーザーのログイン ダイアログを表示する必要があります。

フォームの 1 つを解放しようとしているときに、例外が発生することがあります。これにより、フォームはメモリに残りますが、不明/使用不可の状態になるため、次のユーザーにフォームを再利用できず、メモリからフォームを削除することもできません。フォームはアプリケーションによって所有されているため、VCL から「MyForm という名前のコンポーネントは既に存在します」というエラーが発生するため、次のユーザー用にフォームの新しいバージョンを直接作成することはできません。とにかく古いフォームインスタンスをメモリに持つことに。

この場合、他の人がどうするか見てみたいです。ここにいくつかのアイデアがあります:

  • これらの例外が発生した場合はアプリケーションを終了してください。とにかくユーザーはログアウトしているので、アプリを使い終わっている可能性があります。必要に応じて、必要に応じてアプリを再起動します。
  • アプリケーションがフォームを所有しないようにして、フォームの複数のインスタンスを作成できるようにし、解放できない/壊れたフォームが少なくとも非表示になるようにします。
  • 各フォームの名前を動的に生成するか、空白に設定すると、名前が重複したり、VCL から「既に存在します」というエラーが発生したりしなくなります。
  • オブジェクトを解放するときに例外が発生しないように、アプリケーションを適切に作成します (非現実的です。予期しないエラーに対する緊急時対応計画が必要です)。


私の解決策は、上記の元のアイデアの 1 つでした。フォームを解放するループの周りに try/except ブロックを追加しました。例外が発生した場合は、エラー メッセージを表示せずにユーザーに表示し、ExitProcess(0) を呼び出してアプリケーションをすぐに強制終了します。

4

2 に答える 2

6

デストラクタ内から発生した例外を処理する良い方法は本当にありません。また、デストラクタは例外を引き起こす可能性のあることを行うべきではないため、それらが決して発生しないことを期待することを「非現実的」とは呼びません。メモリの解放やその他のクリーンアップ以外のことをしている場合 (ハンドルの解放、接続のクローズなど) は、ほぼ確実に何か間違ったことをしています。

ところで、例外の原因は何ですか? エラーを一貫して再現できますか? あなたの最善の行動は、エラーを修正することです。それらの数が多すぎてはいけません。

于 2010-09-03T21:58:19.013 に答える
5

ほとんどの場合、フォームを破棄するとエラーが発生します。これは、実行中のイベント ハンドラーがまだ存在し、既に破棄されているオブジェクトを参照しているためです。
そのため、そのような場合TForm.Releaseの代わりに使用するために作成されましたTForm.Free

ヘルプから:
Release を使用してフォームを破棄し、関連するメモリを解放します。Release は、フォームのすべてのイベント ハンドラーとフォーム上のコンポーネントのイベント ハンドラーの実行が完了するまで、フォームを破棄しません。Release は、フォームがリリースされる前に、フォームのイベント キュー内のすべてのメッセージが処理されることも保証します。フォームまたはその子のイベント ハンドラは、Free (Delphi) または delete (C++) の代わりに Release を使用する必要があります。そうしないと、メモリアクセスエラーが発生する可能性があります。

于 2010-09-03T22:13:23.660 に答える