Lambda Expression cause weakreference's target cannot be GC?<p>namespace Test<br>{</p> <p>    class Test<br>    {<br>        delegate void HandleMessage(string message);</p> <p>        public void handleMessage(string message){}</p> <p>        static void Main(string[] args)<br>        {<br>            HandleMessage listener1 = new Test().handleMessage;<br>            WeakReference w1 = new WeakReference(listener1);</p> <p>            HandleMessage listener2 = (message) =&gt; { };<br>            WeakReference w2 = new WeakReference(listener2);</p> <p>            Console.WriteLine(&quot;w1.Target:\t[&quot; + w1.Target + &quot;]&quot;);<br>            Console.WriteLine(&quot;w2.Target:\t[&quot; + w2.Target + &quot;]&quot;);</p> <p>            listener1 = null;<br>            listener2 = null;<br>            GC.Collect();<br>            Console.WriteLine(&quot;after GC&quot;);</p> <p>            Console.WriteLine(&quot;w1.Target:\t[&quot; + w1.Target + &quot;]&quot;);<br>            Console.WriteLine(&quot;w2.Target:\t[&quot; + w2.Target + &quot;]&quot;);</p> <p>            Console.ReadLine();<br>        }<br>    }<br>}</p>why w2.Target is not null after GC.<br>---------------------------------------------------------<br>w1.Target:      [Test.Test+HandleMessage]<br>w2.Target:      [Test.Test+HandleMessage]<br>after GC<br>w1.Target:      []<br>w2.Target:      [Test.Test+HandleMessage] © 2009 Microsoft Corporation. All rights reserved.Mon, 16 Feb 2009 01:07:18 Z9569db48-da5c-4f5d-b39f-eb6c125fedd6http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/9569db48-da5c-4f5d-b39f-eb6c125fedd6#9569db48-da5c-4f5d-b39f-eb6c125fedd6http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/9569db48-da5c-4f5d-b39f-eb6c125fedd6#9569db48-da5c-4f5d-b39f-eb6c125fedd6sailing8036http://social.msdn.microsoft.com/Profile/en-US/?user=sailing8036Lambda Expression cause weakreference's target cannot be GC?<p>namespace Test<br>{</p> <p>    class Test<br>    {<br>        delegate void HandleMessage(string message);</p> <p>        public void handleMessage(string message){}</p> <p>        static void Main(string[] args)<br>        {<br>            HandleMessage listener1 = new Test().handleMessage;<br>            WeakReference w1 = new WeakReference(listener1);</p> <p>            HandleMessage listener2 = (message) =&gt; { };<br>            WeakReference w2 = new WeakReference(listener2);</p> <p>            Console.WriteLine(&quot;w1.Target:\t[&quot; + w1.Target + &quot;]&quot;);<br>            Console.WriteLine(&quot;w2.Target:\t[&quot; + w2.Target + &quot;]&quot;);</p> <p>            listener1 = null;<br>            listener2 = null;<br>            GC.Collect();<br>            Console.WriteLine(&quot;after GC&quot;);</p> <p>            Console.WriteLine(&quot;w1.Target:\t[&quot; + w1.Target + &quot;]&quot;);<br>            Console.WriteLine(&quot;w2.Target:\t[&quot; + w2.Target + &quot;]&quot;);</p> <p>            Console.ReadLine();<br>        }<br>    }<br>}</p>why w2.Target is not null after GC.<br>---------------------------------------------------------<br>w1.Target:      [Test.Test+HandleMessage]<br>w2.Target:      [Test.Test+HandleMessage]<br>after GC<br>w1.Target:      []<br>w2.Target:      [Test.Test+HandleMessage] Wed, 11 Feb 2009 08:34:50 Z2009-02-11T08:34:50Zhttp://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/9569db48-da5c-4f5d-b39f-eb6c125fedd6#c466d998-0fa0-410e-86d8-3bc00577908fhttp://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/9569db48-da5c-4f5d-b39f-eb6c125fedd6#c466d998-0fa0-410e-86d8-3bc00577908fHarry Zhuhttp://social.msdn.microsoft.com/Profile/en-US/?user=Harry%20ZhuLambda Expression cause weakreference's target cannot be GC? Hi,<br><br>The Lambda Expression is defined as a private static delegate,and then pushed onto stack . when listener2 is set to null , the Lambda is still referenced , and won't be collected.<br><br>Please check that in the Il code using IL Disassembler.<br><br>If we the code of Main is :<br> <div style="border-right:#7f9db9 1px solid;border-top:#7f9db9 1px solid;font-size:11px;overflow:auto;border-left:#7f9db9 1px solid;line-height:100%! important;border-bottom:#7f9db9 1px solid;font-family:Courier New;background-color:white"> <table style="border-top-width:0px;border-left-width:0px;margin:2px 0px;width:99%;border-bottom:#eee 0px solid;border-collapse:collapse;background-color:#fff;border-right-width:0px" cellspacing=0 cellpadding=0> <colgroup> <col style="padding-left:10px;font-size:11px;border-bottom:#f7f7f7 1px solid;font-family:Courier New;white-space:nowrap"> <tbody> <tr> <td><font style="font-size:11px">static void Main(string[] args)  </font></td></tr> <tr> <td style="background-color:#f7f7f7">        {  </td></tr> <tr> <td>            HandleMessage </font><font style="color:red">listener1</font><font style="font-size:11px"> = </font><font style="color:blue">new</font><font style="font-size:11px"> Test().handleMessage;  </font></td></tr> <tr> <td style="background-color:#f7f7f7">            </td></tr> <tr> <td> </td></tr> <tr> <td style="background-color:#f7f7f7">            HandleMessage </font><font style="color:red">listener2</font><font style="font-size:11px"> = (message) =</font><font style="color:blue">&gt;</font><font style="font-size:11px"> { };  </font></td></tr> <tr> <td>         }   </td></tr> <tr> <td style="background-color:#f7f7f7">             </td></tr></tbody></table></div><br>The il code would be:<br> <div style="border-right:#7f9db9 1px solid;border-top:#7f9db9 1px solid;font-size:11px;overflow:auto;border-left:#7f9db9 1px solid;line-height:100%! important;border-bottom:#7f9db9 1px solid;font-family:Courier New;background-color:white"> <table style="border-top-width:0px;border-left-width:0px;margin:2px 0px;width:99%;border-bottom:#eee 0px solid;border-collapse:collapse;background-color:#fff;border-right-width:0px" cellspacing=0 cellpadding=0> <colgroup> <col style="padding-left:10px;font-size:11px;border-bottom:#f7f7f7 1px solid;font-family:Courier New;white-space:nowrap"> <tbody> <tr> <td><font style="font-size:11px">.method private hidebysig static void  Main(string[] args) cil managed  </font></td></tr> <tr> <td style="background-color:#f7f7f7">{  </td></tr> <tr> <td>  .entrypoint  </td></tr> <tr> <td style="background-color:#f7f7f7">  // Code size       51 (0x33)  </td></tr> <tr> <td>  .maxstack  3  </td></tr> <tr> <td style="background-color:#f7f7f7">  .locals init ([0] class linq_relating_to_weak_reference.Test/HandleMessage listener1,  </td></tr> <tr> <td>           [1] class linq_relating_to_weak_reference.Test/HandleMessage listener2)  </td></tr> <tr> <td style="background-color:#f7f7f7">  IL_0000:  nop  </td></tr> <tr> <td>  IL_0001:  newobj     instance void linq_relating_to_weak_reference.Test::.ctor()  </td></tr> <tr> <td style="background-color:#f7f7f7">  IL_0006:  ldftn      instance void linq_relating_to_weak_reference.Test::handleMessage(string)  </td></tr> <tr> <td>  IL_000c:  newobj     instance void linq_relating_to_weak_reference.Test/HandleMessage::.ctor(object,  </td></tr> <tr> <td style="background-color:#f7f7f7">                                                                                               native int)  </td></tr> <tr> <td>  IL_0011:  stloc.0  </td></tr> <tr> <td style="background-color:#f7f7f7"><font style="background-color:#ffcccc">  IL_0012:  ldsfld     class linq_relating_to_weak_reference.Test/HandleMessage linq_relating_to_weak_reference.Test::'CS$</font><font style="color:blue">&lt;</font></font><font style="font-size:11px"><font style="background-color:#ffcccc">&gt;9__CachedAnonymousMethodDelegate1'</font>  </font></td></tr> <tr> <td>  IL_0017:  brtrue.s   IL_002c  </td></tr> <tr> <td style="background-color:#f7f7f7">  IL_0019:  ldnull  </td></tr> <tr> <td>  IL_001a:  ldftn      void linq_relating_to_weak_reference.Test::'</font><font style="color:blue">&lt;</font><font style="font-size:11px">Main</font><font style="color:blue">&gt;</font><font style="font-size:11px">b__0'(string)  </font></td></tr> <tr> <td style="background-color:#f7f7f7">  IL_0020:  newobj     instance void linq_relating_to_weak_reference.Test/HandleMessage::.ctor(object,  </td></tr> <tr> <td>                                                                                               native int)  </td></tr> <tr> <td style="background-color:#f7f7f7">  IL_0025:  stsfld     class linq_relating_to_weak_reference.Test/HandleMessage linq_relating_to_weak_reference.Test::'CS$</font><font style="color:blue">&lt;</font><font style="font-size:11px">&gt;9__CachedAnonymousMethodDelegate1'  </font></td></tr> <tr> <td>  IL_002a:  br.s       IL_002c  </td></tr> <tr> <td style="background-color:#f7f7f7">  IL_002c:  ldsfld     class linq_relating_to_weak_reference.Test/HandleMessage linq_relating_to_weak_reference.Test::'CS$</font><font style="color:blue">&lt;</font><font style="font-size:11px">&gt;9__CachedAnonymousMethodDelegate1'  </font></td></tr> <tr> <td>  IL_0031:  stloc.1  </td></tr> <tr> <td style="background-color:#f7f7f7">  IL_0032:  ret  </td></tr> <tr> <td>} // end of method Test::Main  </td></tr> <tr> <td style="background-color:#f7f7f7"> </td></tr></tbody></table></div><br>Code on line 12 shows: <p></p> <p><font style="background-color:#ffcccc">ldsfld</font> pushes the value of a static field onto the evaluation stack. <br><br><font style="background-color:#ffcccc">'CS$</font><font style="color:blue">&lt;</font></font><font style="font-size:11px"><font style="background-color:#ffcccc">&gt;9__CachedAnonymousMethodDelegate1'</font>  </font>is the static field generated by compiler.<br><br>then on line 25 ,<br><br>listener2 is set to the compiler generated delegate.<br><br><br>Best regards,<br>Harry</p>Fri, 13 Feb 2009 07:58:12 Z2009-02-13T07:58:12Zhttp://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/9569db48-da5c-4f5d-b39f-eb6c125fedd6#9a297b7d-776e-4b60-81b5-cb5fbbefda7ahttp://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/9569db48-da5c-4f5d-b39f-eb6c125fedd6#9a297b7d-776e-4b60-81b5-cb5fbbefda7asailing8036http://social.msdn.microsoft.com/Profile/en-US/?user=sailing8036Lambda Expression cause weakreference's target cannot be GC?<p>Thank Harry for your correct reply.<br><br><a href="http://stackoverflow.com/questions/535972/lambda-expression-cause-weakreferences-target-cannot-be-gc">http://stackoverflow.com/questions/535972/lambda-expression-cause-weakreferences-target-cannot-be-gc</a><br>I also got the answer from above。<br><br>The following example show that :<br><br>if Test#create() method don't reference to any Test instance object's properties or methods, then &quot;private static HandleMessage CS$&lt;&gt;9__CachedAnonymousMethodDelegate1&quot; will be created by compiler, like what Jon Skeet has said - That makes it more efficient when you use the same lambda expression multiple times. </p> <p>if Test#create() method reference to any Test instance object's properties or methods, like the example below calling this.toString(); then compiler can not create static method to replace the intstance's method logic, so after GC the HandleMessage instance can be collected.</p> <p>namespace Test {</p><pre class=prettyprint><code><span class=kwd>class</span> <span class=typ>Test</span><span class=pln><br></span><span class=pun>{</span><span class=pln><br>    </span><span class=kwd>public</span> <span class=kwd>delegate</span> <span class=kwd>void</span> <span class=typ>HandleMessage</span><span class=pun>(</span><span class=kwd>string</span><span class=pln> message</span><span class=pun>);</span><span class=pln><br><br>    </span><span class=kwd>public</span> <span class=kwd>void</span><span class=pln> handleMessage</span><span class=pun>(</span><span class=kwd>string</span><span class=pln> message</span><span class=pun>)</span><span class=pln><br>    </span><span class=pun>{</span><span class=pln><br>    </span><span class=pun>}</span><span class=pln><br><br>    </span><span class=kwd>public</span> <span class=typ>HandleMessage</span><span class=pln> create</span><span class=pun>()</span><span class=pln><br>    </span><span class=pun>{</span><span class=pln><br>        </span><span class=kwd>return</span> <span class=pun>(</span><span class=pln>message</span><span class=pun>)</span> <span class=pun>=&gt;</span> <span class=pun>{</span><span class=pln> <br>            </span><span class=com>this.ToString(); </span><span class=pln><br>        </span><span class=pun>};</span><span class=pln><br>    </span><span class=pun>}</span><span class=pln>       <br><br>    </span><span class=kwd>static</span> <span class=kwd>void</span> <span class=typ>Main</span><span class=pun>(</span><span class=kwd>string</span><span class=pun>[]</span><span class=pln> args</span><span class=pun>)</span><span class=pln><br>    </span><span class=pun>{</span><span class=pln><br>        </span><span class=typ>HandleMessage</span><span class=pln> listener1 </span><span class=pun>=</span> <span class=kwd>new</span> <span class=typ>Test</span><span class=pun>().</span><span class=pln>handleMessage</span><span class=pun>;</span><span class=pln><br>        </span><span class=typ>WeakReference</span><span class=pln> w1 </span><span class=pun>=</span> <span class=kwd>new</span> <span class=typ>WeakReference</span><span class=pun>(</span><span class=pln>listener1</span><span class=pun>);</span><span class=pln><br><br>        </span><span class=typ>HandleMessage</span><span class=pln> listener2 </span><span class=pun>=</span> <span class=kwd>new</span> <span class=typ>Test</span><span class=pun>().</span><span class=pln>create</span><span class=pun>();</span><span class=com>//(message) =&gt; { };</span><span class=pln><br>        </span><span class=typ>WeakReference</span><span class=pln> w2 </span><span class=pun>=</span> <span class=kwd>new</span> <span class=typ>WeakReference</span><span class=pun>(</span><span class=pln>listener2</span><span class=pun>);</span><span class=pln><br><br>        </span><span class=typ>Console</span><span class=pun>.</span><span class=typ>WriteLine</span><span class=pun>(</span><span class=str>&quot;w1.Target:\t[&quot;</span> <span class=pun>+</span><span class=pln> w1</span><span class=pun>.</span><span class=typ>Target</span> <span class=pun>+</span> <span class=str>&quot;]&quot;</span><span class=pun>);</span><span class=pln><br>        </span><span class=typ>Console</span><span class=pun>.</span><span class=typ>WriteLine</span><span class=pun>(</span><span class=str>&quot;w2.Target:\t[&quot;</span> <span class=pun>+</span><span class=pln> w2</span><span class=pun>.</span><span class=typ>Target</span> <span class=pun>+</span> <span class=str>&quot;]&quot;</span><span class=pun>);</span><span class=pln><br><br>        listener1 </span><span class=pun>=</span> <span class=kwd>null</span><span class=pun>;</span><span class=pln><br>        listener2 </span><span class=pun>=</span> <span class=kwd>null</span><span class=pun>;</span><span class=pln><br>        GC</span><span class=pun>.</span><span class=typ>Collect</span><span class=pun>();</span><span class=pln><br>        </span><span class=typ>Console</span><span class=pun>.</span><span class=typ>WriteLine</span><span class=pun>(</span><span class=str>&quot;after GC&quot;</span><span class=pun>);</span><span class=pln><br><br>        </span><span class=typ>Console</span><span class=pun>.</span><span class=typ>WriteLine</span><span class=pun>(</span><span class=str>&quot;w1.Target:\t[&quot;</span> <span class=pun>+</span><span class=pln> w1</span><span class=pun>.</span><span class=typ>Target</span> <span class=pun>+</span> <span class=str>&quot;]&quot;</span><span class=pun>);</span><span class=pln><br>        </span><span class=typ>Console</span><span class=pun>.</span><span class=typ>WriteLine</span><span class=pun>(</span><span class=str>&quot;w2.Target:\t[&quot;</span> <span class=pun>+</span><span class=pln> w2</span><span class=pun>.</span><span class=typ>Target</span> <span class=pun>+</span> <span class=str>&quot;]&quot;</span><span class=pun>);</span><span class=pln><br><br>        </span><span class=typ>Console</span><span class=pun>.</span><span class=typ>ReadLine</span><span class=pun>();</span><span class=pln><br>    </span><span class=pun>}</span><span class=pln><br></span><span class=pun>}</span><span class=pln><br></span></code></pre> <p>}<br><br>Best regards,<br>Eric</p>Fri, 13 Feb 2009 15:12:09 Z2009-02-13T15:12:09Z