11

匿名のデリゲートとラムダ式を使用して C# でイベント ハンドラーのメソッドを作成することで、少なくとも私自身は解決したいと思っています。

匿名デリゲートまたはラムダ式のいずれかを追加するイベントがあるとします (新しいバージョンの .NET を使用できる幸運な人々のために)。

SomeClass.SomeEvent += delegate(object o, EventArg e) { /* do something */ };

クラスがガベージ コレクションされるのを防ぐハンドラーがまだあるイベントについて、過去の人々が忘れていることを読んだことがあります。クラス内で SomeEvent を null に設定するだけでなく、追加されたハンドラーを削除するにはどうすればよいでしょうか。以下はまったく新しいハンドラではないでしょうか?

SomeClass.SomeEvent -= delegate(object o, EventArg e) { /* do something */ };

匿名デリゲートまたはラムダ式を変数に格納することがわかりました。しかし、少なくとも私には、イベント ハンドラーを簡単かつ簡潔に追加できるようにするという目的全体が無効になっているように思えます。

SomeEventDelegate handler = new SomeEventDelegate(delegate(object o, EventArg e) { /* do something */ });
SomeClass.SomeEvent += handler;
// ... stuff
SomeClass.SomeEvent -= handler;

繰り返しますが、私はあなたができることを理解しています...

public override Dispose(bool disposing)
{
    _someEvent = null;
    this.Dispose();
}

しかし、イベントから動的に作成されたメソッドを削除するだけで、より興味深いものになります。うまくいけば、誰かが私のためにこれに光を当てることができます. ありがとう!

4

3 に答える 3

10

オブジェクトXにターゲットがオブジェクトYであるイベントハンドラーがある場合、オブジェクトXが有効であるということは、オブジェクトYをガベージコレクションできないことを意味します。オブジェクトXのガベージコレクションが停止することはありません。

通常、何かを処分すると、とにかくすぐにゴミになりますので、問題ありません。

イベントとGCの問題は、サブスクライブされたハンドラーをのオブジェクトから削除するのを忘れた場合です。つまり、破棄されたリスナーがありますが、別のオブジェクトのイベントからの参照がまだあるため、ガベージコレクションは行われません。

于 2009-01-13T14:58:23.143 に答える
1

問題は、オブジェクトのイベントにデリゲートが割り当てられていると、GC されないようにするという仮定から進んでいるように見えることだと思います。

これは単純なステートメントとして正しくありません。

そうは言っても、認識された問題は消えます。

ガベージ コレクションでは、最初はすべてがガベージです。GC は、現在グローバルおよび各スタックで利用可能なすべてのもの、およびそれらが参照している他のオブジェクトなどから実行され、それぞれをガベージではないとマークします。

このようなグラフ化プロセスは、どのようにしてこのオブジェクトにたどり着くのでしょうか?

于 2009-01-13T14:51:33.030 に答える
0

できません。

スコープ外で匿名型を作成できないのと同じように(一部のコンパイラーのトリックを除く)。

それが匿名と呼ばれる理由です。

参照をどこかに保存する必要があります...またはリフレクションを使用します。

于 2009-01-13T15:01:18.580 に答える