<p>I understand what <a href="http://msdn.microsoft.com/en-us/library/ms404247.aspx" rel="noreferrer">System.WeakReference</a> does, but what I can't seem to grasp is a practical example of what it might be useful for. The class itself seems to me to be, well, a hack.  It seems to me that there are other, better means of solving a problem where a WeakReference is used in examples I've seen.  What's the canonical example of where you've really got to use a WeakReference?  Aren't we trying to get <i>farther</i> away from this type of behavior and use of this class?  </p>

[{'answer_id': 15616, 'author': 'Mark Cidade', 'author_id': 1659, 'author_profile': 'https://Stackoverflow.com/users/1659', 'pm_score': 4, 'selected': False, 'text': '<p>I use it to implement a cache where unused entries are automatically garbage collected:</p>\n\n<pre><code>class Cache&lt;TKey,TValue&gt; : IEnumerable&lt;KeyValuePair&lt;TKey,TValue&gt;&gt;\n{ Dictionary&lt;TKey,WeakReference&gt; dict = new Dictionary&lt;TKey,WeakReference&gt;();\n\n   public TValue this[TKey key]\n    { get {lock(dict){ return getInternal(key);}}\n      set {lock(dict){ setInteral(key,value);}}     \n    }\n\n   void setInteral(TKey key, TValue val)\n    { if (dict.ContainsKey(key)) dict[key].Target = val;\n      else dict.Add(key,new WeakReference(val));\n    } \n\n\n   public void Clear() { dict.Clear(); }\n\n   /// &lt;summary&gt;Removes any dead weak references&lt;/summary&gt;\n   /// &lt;returns&gt;The number of cleaned-up weak references&lt;/returns&gt;\n   public int CleanUp()\n    { List&lt;TKey&gt; toRemove = new List&lt;TKey&gt;(dict.Count);\n      foreach(KeyValuePair&lt;TKey,WeakReference&gt; kv in dict)\n       { if (!kv.Value.IsAlive) toRemove.Add(kv.Key);\n       }\n\n      foreach (TKey k in toRemove) dict.Remove(k);\n      return toRemove.Count;\n    }\n\n    public bool Contains(string key) \n     { lock (dict) { return containsInternal(key); }\n     }\n\n     bool containsInternal(TKey key)\n      { return (dict.ContainsKey(key) &amp;&amp; dict[key].IsAlive);\n      }\n\n     public bool Exists(Predicate&lt;TValue&gt; match) \n      { if (match==null) throw new ArgumentNullException("match");\n\n        lock (dict)\n         { foreach (WeakReference weakref in dict.Values) \n            { if (   weakref.IsAlive \n                  &amp;&amp; match((TValue) weakref.Target)) return true;\n         }  \n      }\n\n       return false;\n     }\n\n    /* ... */\n   }\n</code></pre>\n'}, {'answer_id': 15627, 'author': 'Judah Gabriel Himango', 'author_id': 536, 'author_profile': 'https://Stackoverflow.com/users/536', 'pm_score': 7, 'selected': True, 'text': '<p>One useful example is the guys who run DB4O object oriented database. There, WeakReferences are used as a kind of light cache: it will keep your objects in memory only as long as your application does, allowing you to put a real cache on top.</p>\n\n<p>Another use would be in the implementation of weak event handlers. Currently, one big source of memory leaks in .NET applications is forgetting to remove event handlers. E.g.</p>\n\n<pre><code>public MyForm()\n{\n    MyApplication.Foo += someHandler;\n}\n</code></pre>\n\n<p>See the problem? In the above snippet, MyForm will be kept alive in memory forever as long as MyApplication is alive in memory. Create 10 MyForms, close them all, your 10 MyForms will still be in memory, kept alive by the event handler.</p>\n\n<p>Enter WeakReference. You can build a weak event handler using WeakReferences so that someHandler is a weak event handler to MyApplication.Foo, thus fixing your memory leaks!</p>\n\n<p>This isn\'t just theory. Dustin Campbell from the DidItWith.NET blog posted <a href="http://diditwith.net/PermaLink,guid,aacdb8ae-7baa-4423-a953-c18c1c7940ab.aspx" rel="noreferrer">an implementation of weak event handlers</a> using System.WeakReference.</p>\n'}, {'answer_id': 347508, 'author': 'Dmitri Nesteruk', 'author_id': 9476, 'author_profile': 'https://Stackoverflow.com/users/9476', 'pm_score': 2, 'selected': False, 'text': '<p>I use weak reference for state-keeping in mixins. Remember, mixins are static, so when you use a static object to attach state to a non-static one, you never know how long it will be required. So instead of keeping a <code>Dictionary&lt;myobject, myvalue&gt;</code> I keep a <code>Dictionary&lt;WeakReference,myvalue&gt;</code> to prevent the mixin from dragging things for too long.</p>\n\n<p>The only problem is that every time I do an access, I also check for dead references and remove them. Not that they hurt anyone, unless there are thousands, of course.</p>\n'}, {'answer_id': 12124101, 'author': 'hIpPy', 'author_id': 58678, 'author_profile': 'https://Stackoverflow.com/users/58678', 'pm_score': 0, 'selected': False, 'text': '<p>There are two reasons why you would use <code>WeakReference</code>. </p>\n\n<ol>\n<li><p><strong>Instead of global objects declared as static</strong>: Global objects are declared as static fields and static fields cannot be GC\'ed (garbage-collected) until the <code>AppDomain</code> is GC\'ed. So you risk out-of-memory exceptions. Instead, we can wrap the global object in a <code>WeakReference</code>. Even though the <code>WeakReference</code> itself is declared static, the object it points to will be GC\'ed when memory is low. </p>\n\n<p>Basically, use <code>wrStaticObject</code> instead of <code>staticObject</code>.</p>\n\n<pre><code>class ThingsWrapper {\n    //private static object staticObject = new object();\n    private static WeakReference wrStaticObject \n        = new WeakReference(new object());\n}\n</code></pre>\n\n<p>Simple app to prove that static object is garbage-collected when AppDomain is.</p>\n\n<pre><code>class StaticGarbageTest\n{\n    public static void Main1()\n    {\n        var s = new ThingsWrapper();\n        s = null;\n        GC.Collect();\n        GC.WaitForPendingFinalizers();\n    }\n}\nclass ThingsWrapper\n{\n    private static Thing staticThing = new Thing("staticThing");\n    private Thing privateThing = new Thing("privateThing");\n    ~ThingsWrapper()\n    { Console.WriteLine("~ThingsWrapper"); }\n}\nclass Thing\n{\n    protected string name;\n    public Thing(string name) {\n        this.name = name;\n        Console.WriteLine("Thing() " + name);\n    }\n    public override string ToString() { return name; }\n    ~Thing() { Console.WriteLine("~Thing() " + name); }\n}\n</code></pre>\n\n<p>Note from the output below <code>staticThing</code> is GC\'ed at the very end even after <code>ThingsWrapper</code> is - i.e. GC\'ed when <code>AppDomain</code> is GC\'ed.</p>\n\n<pre><code>Thing() staticThing\nThing() privateThing\n~Thing() privateThing\n~ThingsWrapper\n~Thing() staticThing\n</code></pre>\n\n<p>Instead we can wrap <code>Thing</code> in a <code>WeakReference</code>. As <code>wrStaticThing</code> can be GC\'ed, we\'ll need a lazy-loaded method which I\'ve left out for brevity. </p>\n\n<pre><code>class WeakReferenceTest\n{\n    public static void Main1()\n    {\n        var s = new WeakReferenceThing();\n        s = null;\n        GC.Collect();\n        GC.WaitForPendingFinalizers();\n        if (WeakReferenceThing.wrStaticThing.IsAlive)\n            Console.WriteLine("WeakReference: {0}", \n                (Thing)WeakReferenceThing.wrStaticThing.Target);\n        else \n            Console.WriteLine("WeakReference is dead.");\n    }\n}\nclass WeakReferenceThing\n{\n    public static WeakReference wrStaticThing;\n    static WeakReferenceThing()\n    { wrStaticThing = new WeakReference(new Thing("wrStaticThing")); }\n    ~WeakReferenceThing()\n    { Console.WriteLine("~WeakReferenceThing"); }\n    //lazy-loaded method to new Thing\n}\n</code></pre>\n\n<p>Note from output below that <code>wrStaticThing</code> is GC\'ed when GC thread is invoked.</p>\n\n<pre><code>Thing() wrStaticThing\n~Thing() wrStaticThing\n~WeakReferenceThing\nWeakReference is dead.\n</code></pre></li>\n<li><p><strong>For objects that are time-consuming to initialize</strong>: You do not want objects that are time-consusming to init to be GC\'ed. You can either keep a static reference to avoid that (with cons from above point) or use <code>WeakReference</code>. </p></li>\n</ol>\n'}]
['https://Stackoverflow.com/questions/15593', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1875/']