2

次のプログラムでは...

using System;

class Program
{
    static Parent parent;

    static void Main( string[] args )
    {
        parent = new Parent();
        // The program hereafter runs for a long time and occasionally
        // causes parent.SomeEvent to be raised.
    }
}

class Parent
{
    public event EventHandler SomeEvent;

    public Parent()
    {
        new Handler( this );
    }
}

class Handler
{
    public Handler( Parent parent )
    {
        parent.SomeEvent += parent_SomeEvent;
    }

    void parent_SomeEvent( object sender, EventArgs e )
    {
        // Does something important here.
    }
}

インスタンス化されたHandlerオブジェクトは、サブスクライブされていますが、参照されていないことに注意してくださいSomeEvent。プログラムがしばらく実行された後、ガベージ コレクターがHandlerインスタンスを削除することを決定し、そのparent_SomeEventハンドラーが発生するたびに呼び出されなくなる可能性はありparent.SomeEventますか?

私が書いているアプリについては、この説明が必要です。Handler上記のように、参照されずにインスタンス化される のようなオブジェクトが多数あります。の主な目的Handlerは、 にサブスクライブすることSomeEventです。インスタンスへの参照に対して呼び出す便利なメソッドはないHandlerため、それ以外の場合は参照しなくても問題ありません。デバッグ中に問題が発生したことはありません。しかし、アプリが長時間実行され、ガベージ コレクターがよりアクティブになっている場合、展開後に問題が発生する可能性があることを懸念しています。

4

3 に答える 3

5

クラスのインスタンス化Handlerされたオブジェクトは、そのオブジェクトへのすべての参照が削除されるまでガベージ コレクションされません。

したがって、すべてのイベント ハンドラーのサブスクライブを解除するまで、オブジェクトは存続します。Parentサブスクライブされたイベント ハンドラは、インスタンスをインスタンスに接続する別の「参照」でもあるためHandlerです。

プログラムがしばらく実行された後、ガベージ コレクターが Handler インスタンスを削除することを決定し、そのため、parent.SomeEvent が発生するたびにそのparent_SomeEventハンドラーが呼び出されなくなる可能性はありますか?

これがまさに、GC がヒープから「参照されていない」オブジェクトのみを収集する理由です。あなたのシナリオは未定義NullReferenceExceptionの s になり、GC がオブジェクトの削除を決定するたびに完全に依存します。幸いなことに、そうではありません:)。

さらに、GC は、参照されていないオブジェクト (参照されていない島) の孤立したプールを判断するのに十分なほどインテリジェントです。したがって、シナリオでは、親オブジェクトも参照されなくなります。GC は、オブジェクトのチェーン全体 (Parentオブジェクト、eventサブスクリプション、およびhandlerオブジェクト) が参照されていないと判断し、次の収集サイクルでそれらをすべてまとめて収集します。

よろしければ、この MSDNの記事をお勧めします。.NET におけるガベージ コレクションの幅広い概念の概要を説明しています。コーディング中に覚えておくと非常に便利です。

于 2013-03-12T19:38:27.363 に答える
3

Programは常に存在し、 Parentのインスタンスを参照しているため、Parentがガベージ コレクションされることはありません (プログラムが終了するまで)。

は、そのイベント ハンドラーSomeEventを通じてデリゲートのコレクションを保持するため、そこにあるデリゲートはガベージ コレクションされません。

要するに、いいえ、ガベージコレクションされません。

于 2013-03-12T19:40:02.033 に答える
2

プログラムを実行すると、ParentクラスはコンストラクターでEventHandler作成しているデリゲート インスタンスへの参照を保持し、デリゲート インスタンスはインスタンスへの参照を保持します。したがって、インスタンスへの参照がある限り、インスタンスはガベージ コレクションされません。HandlerHandlerHandlerParent

于 2013-03-12T19:40:02.943 に答える