むらさんの .NETのメモリ管理 を読んでからずっと WeakReference って便利そうだから何か使う機会が欲しいなぁと思ってたのですが、最近ようやく見つけましたw
XML からデシリアライズしたクラスを使ってると、実体 TValue を string や int をキーにして TValue を参照しているということがよくあって、そのために Dictionary という形で Dictionary を使用して参照していました。
こうすることによって、Dictionary の中身をシリアル化するだけで TValue は全て保存できます。
で、この Dictionary は外部に公開せず、TValue への参照を作った時点で自動的に追加されます。
しかし、削除するときは参照だけしか消さないので、Dictionary はどんどん肥大化していってしまいます。
何とか参照されていない TValue は削除出来ないかなぁ、と思った時に思い浮かんだのが WeakReference です。
こんな実装をしてみました。
public void RemoveDeadValue<TKey, TValue>(Dictionary<TKey, TValue> dictionary)
{
Dictionary<WeakReference, TKey> tempDictionary = new Dictionary<WeakReference, TKey>();
foreach (KeyValuePair<TKey, TValue> pair in dictionary)
{
tempDictionary.Add(new WeakReference(pair.Value), pair.Key);
}
dictionary.Clear();
GC.Collect();
foreach (KeyValuePair<WeakReference, TKey> pair in tempDictionary)
{
TValue value = (TValue)pair.Key.Target;
if (value != null)
{
dictionary.Add(pair.Value, value);
}
}
}
Dictionary の TValue を WeakReference に入れて GC で回収しています。
GC は何度かやらないときれいには回収できませんが、肥大化を防げたらいいだけなので気にしないことにします。
他にも WeakReference の有用な使い道があれば教えて下さいm(__)m