11

次のような方法がある場合:

public void Show()
{
   Form1 f = new Form1();
   f.ShowDialog();
}

ガベージ コレクションの対象となる範囲外になっても、フォームでdispose を呼び出す必要がありますか。

いくつかのテストから、この Show() を複数回呼び出す.. ある時点で、メモリの急上昇が見られるため、GC がそれを収集し、ある時点でダウンするように見えます。

MSDN からは、フォームが不要になったときに dispose を呼び出さなければならないと言っているようです。

4

7 に答える 7

15

発生する傾向があるのは、アイテムが純粋に管理されたリソースを持っている場合、 dispose を呼び出すことは必ずしも必要ではありませんが、破棄が決定論的になるため、強くお勧めします。これらの管理対象リソース自体が GC の対象となる可能性が高いため、(技術的な意味で) 常に必要とは限りません。または、実際にはデフォルトで破棄するものがなく、拡張ポイントであるためです。

管理されていないリソースの場合、Disposeパターンは、GC で呼び出されるfinalizerの実装を推奨しています。型がファイナライザーを実装せず、dispose が呼び出されない場合、リソースが未処理のままになる可能性があります(まあ、非常に可能性が高いです)。ファイナライザーは、ランタイムが提供する最後のチャンスであり、時間制限もあります。

GC またはマネージ メモリの再利用を決定論的にしないことに注意してください。破棄はC++ からではありません。 delete廃棄されたアイテムは、実際に回収されるまでにはかなりの時間がかかる可能性があります。ただし、管理された世界では、決定論的なコレクションは気にせず、リソースの管理、つまり廃棄のみを行います。

とは言うものの、私は常に Dispose を呼び出すか、型が使い捨ての場合はステートメントを使用するようusingしています。

public void Show()
{
    using (var f = new Form1())
    {
        f.ShowDialog();
    } // Disposal, even on exceptions or nested return statements, occurs here.
}

アップデート:

Servy との話し合いの結果、この点を可能な限り処分するという私のアドバイスの背後にある理由として表明しなければならないと感じています. の場合、MemoryStream明らかに使い捨てタイプですが、実際には現在何も処分していません。

ただし、これに依存することは、 の実装に依存することになりMemoryStreamます。MemoryStreamこれが管理されていないリソースを含むように変更された場合、これは、処分するものが何もないことに依存することが問題になることを意味します。

可能であれば ( の場合のように)、公的な契約IDisposableに頼ることを好みます。この場合、コントラクトに反する作業を行うということは、基になる実装の変更から保護されていることを意味します。

于 2012-07-12T14:41:42.263 に答える
4

C# imo で手動で破棄する必要はめったにありませんが、次のように試すことができます。

    public void Show()
    {
       using (Form1 f = new Form1())
       {
         f.ShowDialog();
       }
    }

その後、使用部分の最後の称賛で、それは自動的に破棄されます。

于 2012-07-12T14:42:35.627 に答える
3

あなたは単に行うことができます:

using (var f = new Form1())
   f.ShowDialog();
于 2012-07-12T14:41:48.880 に答える
2

明示的に処分したい場合は、

 using(Form1 f = new Form1()){

            f.ShowDialog();
        }

これにより、Dispose() が確実に呼び出され、すぐに発生します。

于 2012-07-12T14:42:08.303 に答える
1

あなたの特定の例では、いいえ、それが特に役立つ可能性は低いです。フォームは大量のリソースを保持するわけではないため、コードの一部がクリーンアップされるのに少し時間がかかる場合でも、問題は発生しません。そのフォームがたまたまビデオの再生に使用されるコントロールを保持している場合、実際にはかなりの数のリソースを保持している可能性があり、dispose メソッドでそれらのリソースを実際に破棄する場合は、価値があります。時間をかけて破棄を呼び出します。ただし、フォームの 99% では、Dispose メソッドは空であり、それを呼び出すかどうかがプログラムに影響を与える (または顕著な) 可能性はほとんどありません。

これが存在する主な理由は、リソースが重要な 1% のケースでリソースを破棄できるようにするためです。

Formaが閉じられているとき、そのDisposeメソッドはすでに呼び出されていることにも注意してください。フォームを閉じる前に Forms リソースを破棄する場合にのみ、usingまたは明示的な呼び出しを追加する必要があります。Dispose(それは私には一般的に悪い考えのように聞こえます)。これは簡単にテストできます。2 つのフォームを含むプロジェクトを作成するだけです。2 番目のフォームでイベント ハンドラーをイベントにアタッチしDisposing、メッセージ ボックスなどを表示します。次に、そのフォームのインスタンスを作成して表示すると (ダイアログとしてかどうかに関係なく)、フォームを閉じたときにメッセージ ボックスがすぐにポップアップすることがわかります。usingまたはDispose呼び出しを追加する必要があります。

于 2012-07-12T15:08:27.073 に答える