button('hey')
вызывает функцию, а не устанавливает ее как обратный вызов.
Одним полезным примером являются парни, которые выполняют объектно-ориентированную базу данных DB4O. Там, WeakReferences используются как своего рода легкий кэш: это сохранит Ваши объекты в памяти только, пока Ваше приложение делает, позволяя Вам поместить реальный кэш на вершину.
Другое использование было бы в реализации слабых обработчиков событий. В настоящее время один большой источник утечек памяти в приложениях.NET забывает удалять обработчики событий. Например,
public MyForm()
{
MyApplication.Foo += someHandler;
}
Посмотрите проблему? В вышеупомянутом отрывке MyForm будет поддержан в памяти навсегда, пока MyApplication жив в памяти. Создайте 10 MyForms, закройте их всех, Ваши 10 MyForms все еще будут в памяти, поддержанной обработчиком событий.
Вводят WeakReference. Можно создать слабое использование обработчика событий WeakReferences так, чтобы someHandler был слабым обработчиком событий к MyApplication. Нечто, таким образом фиксируя Ваши утечки памяти!
Это не просто теория. Dustin Campbell из блога DidItWith.NET отправил реализация слабых обработчиков событий Система использования. WeakReference.
Я использую слабую ссылку для хранения состояния в mixins. Помните, mixins статичны, поэтому при использовании статического объекта для присоединения состояния к нестатическому, Вы никогда не знаете, сколько времени оно будет требоваться. Таким образом вместо того, чтобы сохранить Dictionary<myobject, myvalue>
я остаюсь Dictionary<WeakReference,myvalue>
, чтобы препятствовать тому, чтобы смешивание перетащило вещи слишком долго.
единственная проблема состоит в том, что каждый раз я делаю доступ, я также проверяю на мертвые ссылки и удаляю их. Не то, чтобы они причиняют любому боль, если нет тысячи, конечно.
Я использую его для реализации кэша, где неиспользованные записи автоматически собраны "мусор":
class Cache<TKey,TValue> : IEnumerable<KeyValuePair<TKey,TValue>>
{ Dictionary<TKey,WeakReference> dict = new Dictionary<TKey,WeakReference>();
public TValue this[TKey key]
{ get {lock(dict){ return getInternal(key);}}
set {lock(dict){ setInteral(key,value);}}
}
void setInteral(TKey key, TValue val)
{ if (dict.ContainsKey(key)) dict[key].Target = val;
else dict.Add(key,new WeakReference(val));
}
public void Clear() { dict.Clear(); }
/// <summary>Removes any dead weak references</summary>
/// <returns>The number of cleaned-up weak references</returns>
public int CleanUp()
{ List<TKey> toRemove = new List<TKey>(dict.Count);
foreach(KeyValuePair<TKey,WeakReference> kv in dict)
{ if (!kv.Value.IsAlive) toRemove.Add(kv.Key);
}
foreach (TKey k in toRemove) dict.Remove(k);
return toRemove.Count;
}
public bool Contains(string key)
{ lock (dict) { return containsInternal(key); }
}
bool containsInternal(TKey key)
{ return (dict.ContainsKey(key) && dict[key].IsAlive);
}
public bool Exists(Predicate<TValue> match)
{ if (match==null) throw new ArgumentNullException("match");
lock (dict)
{ foreach (WeakReference weakref in dict.Values)
{ if ( weakref.IsAlive
&& match((TValue) weakref.Target)) return true;
}
}
return false;
}
/* ... */
}