2016-09-14 8 views
6

私のアプリでは、フォームの新しいインスタンスをその場で作成し、Form.Show()を使用してフォームを表示します(非モーダル)。新しいフォームをすぐに処理しないで処分する適切な方法は何ですか?

private void test_click(object sender, EventArgs e) 
{ 
    var form = new myForm(); 
    form.Show(); 
} 

ただし、コードクラッカーは、これらのフォームを削除する必要があることを伝えています。そこで、私はそれらを "using"ステートメントでラップしましたが、開かれた直後に閉じます。

using (var form = new myForm()) 
{ 
    form.Show(); 
} 

少数の例では、私が唯一のレポートを表示する新しいウィンドウを開くてるので、私は、Form.ShowDialog()を使用する必要はありません。私はそれらがモーダルである必要はありません。あなたはそれを示し、各フォームのOnFormClosedEventに加入しますフォームマネージャのsomekindを実装することができ

+6

答えは明らかです。 "コードクラッカー"があなたを誤って案内します。 'using'を使わないでください....適切なときにフォームを廃棄してください... –

+0

ここで@ L.Bに同意する必要があります。ウィンドウを閉じることはDispose()が行うべき正しいことです。定義上、正しく実装されたDispose()メソッドは、配置されたオブジェクトを使用不可能な状態のままにしておく必要があります。 – EJoshuaS

+1

この[スレッド]を読む(https://social.msdn.microsoft.com/Forums/windows/en-US/cc4acf77-6e7e-46a6-992d-702e314acbdf/howwhen-to-call-dispose-when-using-a) -modeless-dialog?forum = winforms)は、処分を心配する必要はないはずです。非モーダルフォームは自動的にGCされます。私はTask Manangerを見ながらテストし、メモリは再利用されています。 – javon27

答えて

3

「コードクラッカー」は、そのツールにとって非常に適切な用語であるように思われます。そのアドバイスは、あなたのプログラムを破壊するコードを作成することを確実にしました。ゴールデンルールはになりません静的コード解析ツールのIDisposableアドバイスは、コード実行で十分な洞察力を持っていません。彼らは決してDispose()コールがその仕事を終わらせるかどうかを決めることはできません。

見ることができないのは、Formクラスが既にそれ自体を処理する方法を知っていることです。これを行うのは非常に簡単ですが、ウィンドウを閉じるとオブジェクトは使用できなくなります。それ以上のウィンドウがない場合は、Formオブジェクトをそのまま使用する必要はありません。 .NETではそれほど一般的ではありませんが、確かに45年前にXeroxで働いていた非常にスマートなプログラマーから鼓舞された贅沢です。

Windowsを表示するためにShowDialog()を使用すると、ではなく、が自動的に破棄されるという特別な規則があります。これは意図的なもので、ダイアログの結果をあまりにも危険なものにするのは危険です。 ステートメントを使用してShowDialog()呼び出しを行うのは非常に簡単ですが、呼び出しがウィンドウが閉じられるまで戻りません。

+0

あなたはすべてのアカウントの権利を持っています。私はCode Crackerのすべての波線を見るのが嫌いですが、同時に抑制ルールを追加したくありません。私はまた、このジュニア開発者のための十分な洞察を提供するので、それを完全に取り除きたいとは思わない。 – javon27

+0

特定の分析ルールをオフにするだけでは、まったく役に立ちません。または、ツールをあまり信頼しないことを学ぶ、上級者になります。 –

1

、それは、それらを配置することができます...のようなもの:

public class FormManager 
{ 
    public T ShowForm<T>() 
     where T : Form, new() 
    { 
     var t = new T(); 
     t.OnFormClosing += DisposeForm; 
     return t; 
    } 

    void DisposeForm(object sender, FormClosedEventArgs args) 
    { 
     ((Form)sender).Dispose(); 
    } 
} 

あなたも、これまでに実装すると行くことができますIDisposableを入力し、マネージャーが処分されたときに未処理のフォームをすべて廃棄してください:)

0

MSDNの回答に従って、非モーダルフォームは、いつでも閉じることができます。

私はテストフォームを複数回開いて閉じてテストすることにしました。私は同時に複数のインスタンスを開いた。 1,2秒後に、これらのフォームで使用されていたメモリが再利用され、適切に処分されたことを示します。

+0

実際、これはGCがメモリを再利用していることを意味し、「Dispose」は呼び出されていません。この場合、 'Dispose'はネイティブリソースをクリーンアップしないので、すべてのメモリはGCによって管理され、' Dispose'が呼び出されたかどうかにかかわらず解放されます。 – Cameron

8

フォームが閉鎖された後にフォームを廃棄する必要がありますか?

Formを閉じると、WM_CLOSEメッセージがウィンドウに送信されます。モーダルフォームの場合

  • (あなたがShowDialogを使用して示された)、Disposeメソッドが呼び出されず、フォームは後に存在する:あなたはWM_CLOSEメッセージを処理WmClose方法のソースコードを見てみる場合は、次のように表示されますプロパティを使用してデータを取得したり、再度表示することができます。

  • ノンモーダルフォーム(Showを使用して示した)では、フォームが閉じられた後にDisposeメソッドが呼び出されます。だからここ

は結論である:

  • あなたがする必要はありません(とあなたがすることはできません)Disposeを呼び出すShow方法を使用してフォームを表示する場合。フォームは閉鎖された後にそれ自体で処分される。

  • ShowDialogを使用してフォームを表示する場合は、Disposeを手動で呼び出す必要があります。良い例は、usingブロックのモーダルフォームを使用することです。

+1

ありがとう、それは非モーダルフォームが自動的にディスポーザルコールを取得し、モデルフォームは取得しないことを知っておいていただきありがとうございます。 –

関連する問題