...そっかー、eventが保持するdelegateは強参照なのか。
delegate void Update();
class Speaker {
public event Update OnUpdate;
public void Notify() { OnUpdate(); }
}
class Listener {
private static int instances_;
private static int notifications_;
private int id_;
public Listener() { // 生成(construct)
id_ = instances_++;
System.Console.WriteLine(" Listener:{0}", id_);
}
~Listener() { // 廃棄(dispose)
System.Console.WriteLine("~Listener:{0}", id_);
--instances_;
}
public void Listen() { // イベントハンドラ
++notifications_;
System.Console.WriteLine(" Listener:{0} LISTEN:{1}", id_, notifications_);
}
}
class Program {
public static void Main() {
Speaker s = new Speaker();
for ( int i = 0; i < 10000; ++i ) {
// Listenerの有効範囲はfor-loop内
Listener l = new Listener();
s.OnUpdate += l.Listen; // ハンドラ登録
s.Notify();
}
}
}
こんなコードを書いて走らす。Listenerはfor-loopの中なので、
loopひと回りしたら要済みになってDispose...されないのね。
Senderが持つeventがListener.Listenを捕まえて離さないから
ガベコレされないわけだ。
使わんくなったらこまめに
s.OnUpdate -= l.Listen;
して呪縛を解いてあげないと。
うっかり忘れてぢわぢわとメモリを食い潰しそう。
気ぃつけなあきませんな。