8

何千ものフォームを含む Windows フォーム アプリケーションがあります。

これらの多くは、ShowDialog() メソッドを介してダイアログとして一時的に表示されます。

このアプリケーションは何年も前から存在しており、フォームまたはそれが使用するコントロールでのさまざまなリソース リークが原因で、多くのフォームでガベージ コレクションがタイムリーに行われていないことがわかりました。

具体的には、適切に破棄されていない GDI+ リソースの例が見つかりましたが、まだ特徴付けられていない他の種類のリソース リークがある可能性があります。

これを解決する正しい方法は、明らかに、すべてのフォームとすべてのコントロールを調べて、すべてのリソースの問題を排除することです。これには時間がかかります。

短期的な代替手段として、フォームで明示的に Dispose() を呼び出すとガベージ コレクション プロセスが開始され、フォームとそのリソースの割り当てがすぐに解除されることがわかりました。

私の質問は、フォームが表示された後に Dispose() が呼び出されるように、各フォームの ShowDialog() ブロックを using ステートメントでラップすることが合理的な回避策であるかどうかです。

たとえば、既存のコードを次のように変更します。

public void ShowMyForm()
{
    MyForm myForm = new MyForm();
    myForm.ShowDialog();
}

これに:

public void ShowMyForm()
{
    using (MyForm myForm = new MyForm())
    {
        myForm.ShowDialog();
    }
}

私たちのテストでは、最初の例では MyForm の Dispose() メソッドが呼び出されることはありませんが、2 番目の例ではすぐに呼び出されます。

これは、特定のリソースの問題をそれぞれ追跡するのに時間を費やしている間、短期的な回避策として合理的なアプローチのように思えますか?

これらのタイプのリソースの問題を特定して解決するための短期的な回避策や方法論として検討できる他のアプローチはありますか?

4

3 に答える 3

14

MSDNによると、ShowDialog を使用して表示されるフォームで Dispose を明示的に呼び出す必要があります (Show メソッドとは異なります)。

フォームがモーダル ダイアログ ボックスとして表示されている場合、[閉じる] ボタン (フォームの右上隅にある X の付いたボタン) をクリックすると、フォームが非表示になり、DialogResult プロパティが DialogResult.Cancel に設定されます。非モーダル フォームとは異なり、Close メソッドは、ユーザーがダイアログ ボックスのフォームを閉じるボタンをクリックしたり、DialogResult プロパティの値を設定したりしたときに、.NET Framework によって呼び出されません。代わりにフォームが非表示になり、ダイアログ ボックスの新しいインスタンスを作成せずに再度表示できます。ダイアログ ボックスとして表示されるフォームは閉じられるのではなく非表示になるため、フォームがアプリケーションで不要になったときに、フォームの Dispose メソッドを呼び出す必要があります。

于 2011-11-29T17:39:11.063 に答える
2

モーダル ダイアログの場合は、次のパターンを使用する必要があります。

using ( var dlg = new MyDialog() )
{
    // other code here to initialize, etc.
    dlg.ShowDialog();
}

MyDialogは Form から派生し、FormはIDisposableを実装するため、このパターンはダイアログを正しくクリーンアップします。

これは「短期的な回避策」ではなく、すべてのモーダル ダイアログを呼び出す標準的な方法です。

モードレスダイアログは別の話です。それらを自分で追跡し、アプリケーションの適切なポイントでDisposeを呼び出す必要があります。

于 2011-11-29T17:44:52.273 に答える
1

using一般に、 IDisposable を実装するオブジェクトに対してステートメントを使用するのは良い方法です。

ちょっとしたサンプル状況:

サードパーティの「コンポーネント」があるとしましょう。内部で何が起こっているのかを知ることはできず、おそらくこのオブジェクトは一時ファイルを作成し、上のファイルを削除しますDispose。電話Dispose()も使用もしない場合using、ファイルは決して削除されません。

あなたの場合、フォームを開く限り、それを行うこともできますmodal

于 2011-11-29T17:37:01.750 に答える