<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx</link><description>I wrote a little bit on Disposable objects and their uses in Chapter 5 of the Performance and Scalability PAG (look here and the following sections) and it triggered a lively discussion here at MS the other day. Here&amp;#8217;s the bit of interest and some</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#135740</link><pubDate>Thu, 20 May 2004 09:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:135740</guid><dc:creator>David Levine</dc:creator><description>The topic of Finalization and Dispose gets complicated pretty quickly - there are lots of variations. One of the problems we've run into is that you can't really get very far without using some underlying system resource or legacy API (e.g. COM) that has destructor semantics (Open/Close, or Create/Destroy) associated with it. &lt;br&gt;&lt;br&gt;We've gotten to the point where we have our own internal guidelines for classes that need either a finalizer or a Dispose.&lt;br&gt;&lt;br&gt;1. If you need either one then you must implement both.&lt;br&gt;&lt;br&gt;2. The Dispose method calls GC.SuppressFinalize(this) after performing the dispose operation. We usually provide a method Dispose(bool disposing) for this; it seems to be almost a standard approach anyway.&lt;br&gt;&lt;br&gt;3. The finalizer calls the same dispose method. &lt;br&gt;&lt;br&gt;4. Clients consuming a class with a Dispose method are required to treat it as part of the contract; if it has a Dispose() method it must call it when the object is no longer needed.&lt;br&gt;&lt;br&gt;5. In the debug build the finalizer will Assert, throw an exception, print to the debug port, etc., so that developers are made aware that they created an object that they did not properly dispose of and for which they did not honor the Dispose contract. We don't have a guideline yet for the release build, but I tend toward thinking that using a Trace statement is useful to provide breadcrumbs, on the expectation that it ought to happen rarely.&lt;br&gt;&lt;br&gt;6. Minimize the number of classes that need either a finalizer or a Dispose.&lt;br&gt;&lt;br&gt;As with all such rules, these are guidelines only - special cases require special handling.&lt;br&gt;</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#135806</link><pubDate>Thu, 20 May 2004 12:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:135806</guid><dc:creator>Mike Dimmick</dc:creator><description>I'd agree with that but call GC.SuppressFinalize _first_, before doing anything else. I've actually seen (on Compact Framework) a finalizer be called when in the middle of executing that object's Dispose method. I can only assume that the JIT stopped reporting the reference and a collection happened, causing the object to get onto the freachable queue.</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#135945</link><pubDate>Thu, 20 May 2004 16:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:135945</guid><dc:creator>Rico Mariani</dc:creator><description>David writes:&lt;br&gt;&lt;br&gt;&amp;gt;&amp;gt; 1. If you need either one then you must implement both. &lt;br&gt;&lt;br&gt;If you have a finalizer you should have Dispose but if you have Dispose you don't necessarily need to be finalizable.  Consider an object has finalizable members.  It need not itself be finalizable because should it die its sub-objects go into the finalization queue directly.  However it should be Disposable so that when Disposed it can in turn call dispose on its members.&lt;br&gt;&lt;br&gt;Re: 2&amp;amp;3. There's a recommended pattern for Dispose methods that covers these.  An example is in the PAG (see link in main article).&lt;br&gt;&lt;br&gt;Re: 5. That's a great defensive mechanism but not always possible with objects that have complex lifetime.  I like the Trace idea, it should be rare enough that it doesn't cause a problem at that level.&lt;br&gt;&lt;br&gt;Re: 6.  Amen.</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#136596</link><pubDate>Fri, 21 May 2004 10:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:136596</guid><dc:creator>David Levine</dc:creator><description>Mike,&lt;br&gt;&lt;br&gt;The argument I've heard in favor of calling GC after disposing the object is that if the dispose throws an exception the call to the GC will never be made so you will get a 2nd chance to cleanup on the finalize thread. This never made much sense because if it threw the 1st time, when other managed objects were still valid, there would be an even greater chance it would throw the 2nd time (on the finalizer thread) when there was no guarantee that managed objects were still valid. But all the examples I've seen from MS show it done this way.&lt;br&gt;&lt;br&gt;The issue of thread safety is a different concern. If the object can be disposed by two different threads (not the finalizer) then the disposed object itself should handle the threading issues to prevent multiple simultaneous calls to Dispose from causing problems. If its because the Dispose method may get called from an object at the same time the finalizer thread disposes the object, then a fix may be very simple. &lt;br&gt;&lt;br&gt;In the dispose method add a flag that is used like this...&lt;br&gt;&lt;br&gt;Dispose()&lt;br&gt;{&lt;br&gt;  if ( !disposed )&lt;br&gt;  {&lt;br&gt;    DoSomeCleanup();&lt;br&gt;    this._disposed = true; // set a instance field&lt;br&gt;  }&lt;br&gt;}&lt;br&gt;&lt;br&gt;This should cause the JIT to report a reference to the GC preventing it from getting finalized until the _disposed flag has been set. It still isn't thread safe but it should prevent it from being put on the freachable queue prematurely.&lt;br&gt;</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#136603</link><pubDate>Fri, 21 May 2004 10:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:136603</guid><dc:creator>David Levine</dc:creator><description>Brad,&lt;br&gt;&lt;br&gt;re: 1) Dispose but no finalizer&lt;br&gt;&lt;br&gt;I agree that you don't always need a finalizer but I would argue that it probably should have one if it has a Dispose. I contend that Dispose should be treated as a contract requirement and that not invoking it should be treated as an error. The finalizer provides a mechanism that allows us to catch these omissions. It may be that it isn't strictly neccessary and may add overhead, but if the object's contract is honored the object will never get put on the freachable queue anyway. &lt;br&gt;&lt;br&gt;I would also argue that users of a class should not have incestuous knowledge of its inner workings - they should not &amp;quot;know&amp;quot; that it's ok to not invoke the finalizer. It's implementation can change at any time and invalidate those assumptions.&lt;br&gt;&lt;br&gt;But in the end, it's only a best practices guideline, not a requirement. &lt;br&gt;&lt;br&gt;regards,&lt;br&gt;</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#136878</link><pubDate>Fri, 21 May 2004 17:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:136878</guid><dc:creator>Rico Mariani</dc:creator><description>Dispose() &lt;br&gt;{ &lt;br&gt;if ( !disposed ) &lt;br&gt;{ &lt;br&gt;DoSomeCleanup(); &lt;br&gt;this._disposed = true; // set a instance field &lt;br&gt;} &lt;br&gt;} &lt;br&gt;&lt;br&gt;This sort of thing isn't necessary the &amp;quot;this&amp;quot; pointer is necessarily live while any member is running including DoSomeCleanup -- all manner of disasters would ensue if that was not the case.&lt;br&gt;&lt;br&gt;Sometimes people do see finalization happening concurrently with disposing.  This isn't a normal situation but it is possible with exotic kinds of cleanup -- people often call the standard Dispose of another object in their finalizer -- this is generally a bad idea because the object may itself have already been finalized though it is still live via your object.&lt;br&gt;&lt;br&gt;Remember all the object members of a finalizable object remain live but finalization order is not guaranteed so your members may have already been disposed or finalized.  It's best to ignore them entirely in your finalizer and only release unmanaged state you directly own.  &lt;br&gt;&lt;br&gt;You avoid this problem entirely if you follow my guideline of never having a finalizable object have any state other than the unmanaged state which it owns (i.e. make it a leaf object).&lt;br&gt;&lt;br&gt;When Disposing this is not the case, you should Dispose your members if any.  Keeping in mind that if you have members to dispose, and you're following my guideline, then all you are doing is holding disposable objects and you yourself would not be finalizable because you have no unmanaged state of your own to clean up.&lt;br&gt;&lt;br&gt;There is more detail on this in the PAG at this link&lt;br&gt;&lt;br&gt;&lt;a target="_new" href="http://msdn.microsoft.com/library/en-us/dnpag/html/scalenetchapt05.asp?frame=true#scalenetchapt05_topic13"&gt;http://msdn.microsoft.com/library/en-us/dnpag/html/scalenetchapt05.asp?frame=true#scalenetchapt05_topic13&lt;/a&gt;&lt;br&gt;</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#137354</link><pubDate>Fri, 21 May 2004 19:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:137354</guid><dc:creator>Andy</dc:creator><description>Is there any way to detect if a developer forgot to call Dispose on an object that implements IDisposable without having a finalizer as someone else suggested?  Can FXCop do this?  </description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#137379</link><pubDate>Fri, 21 May 2004 20:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:137379</guid><dc:creator>Rico Mariani</dc:creator><description>Can't do it in general via static analysis (ala FXCop) but maybe some of the more common cases could be handled that way.</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#139495</link><pubDate>Sat, 22 May 2004 15:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:139495</guid><dc:creator>David Levine</dc:creator><description>Rico,&lt;br&gt;&lt;br&gt;re: finalizers running while in a instance method. &lt;br&gt;&lt;br&gt;Are you sure that it is not necessary to ensure the &amp;quot;this&amp;quot; reference is kept alive? My understanding of how the JIT reports references to the GC may be flawed or incomplete. &lt;br&gt;&lt;br&gt;The information I had stated that executing an instance method was not enough to ensure that the JIT would report that instance to be alive. &lt;br&gt;&lt;br&gt;Chris Brumme's article on this &amp;lt;&lt;a target="_new" href="http://blogs.gotdotnet.com/cbrumme/permalink.aspx/e55664b4-6471-48b9-b360-f0fa27ab6cc0&amp;gt;"&gt;http://blogs.gotdotnet.com/cbrumme/permalink.aspx/e55664b4-6471-48b9-b360-f0fa27ab6cc0&amp;gt;&lt;/a&gt; indicates that an instance is eligible for collection even while executing an instance method. &lt;br&gt;&lt;br&gt;In other words, given the statement:&lt;br&gt;&lt;br&gt;new SomeObject(); &lt;br&gt;&lt;br&gt;If the reference to the newly created SomeObject is not used (e.g. not stored in a root) then it can be collected while its constructor is still running.&lt;br&gt;&lt;br&gt;Am I reaching an invalid conclusion here, or has the implementation changed so that this is no longer the case? &lt;br&gt;</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#141556</link><pubDate>Tue, 25 May 2004 18:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:141556</guid><dc:creator>Rico Mariani</dc:creator><description>I'll talk to Chris about it, I think it's worth getting a definitive answer out there.&lt;br&gt;&lt;br&gt;I can say this much though, and this is an important special case.&lt;br&gt;&lt;br&gt;If you write this (as you wrote above):&lt;br&gt;&lt;br&gt;new SomeObject(); &lt;br&gt;&lt;br&gt;The code does not have the new object pointer until after the constructor has finished running.  Whether you then store it afterwords or not cannot make a difference as to what happened during construction.  If the JIT reported a member variable or local of your method as a live root that would be all fine and well but that root couldn't possibly be *holding* the value during the construction anyway because it doesn't yet have the new object reference.&lt;br&gt;&lt;br&gt;So either the constructor itself, or else the CLR in the context of creating the object must necessarily keep the object alive otherwise if a colletion was triggered your object would go away.&lt;br&gt;&lt;br&gt;Speaking very broadly, there are many complex lifetime issues like this and if you had to think about any of them the whole model would be a disaster.  It has to &amp;quot;just work&amp;quot;.&lt;br&gt;&lt;br&gt;Now you can imagine cases where even though a method was running that the &amp;quot;this&amp;quot; pointer is no longer reachable.  If there is truly such a case then collection is perfectly fine, you can't get to the object anymore anyway so it's impossible to know if it's gone as a practical matter anyway.  If someone else can access the object then by definition its still reachable and it won't be discarded even though the member can't reach it.&lt;br&gt;&lt;br&gt;I do not see the point of code like this:&lt;br&gt;&lt;br&gt;DoSomeCleanup(); &lt;br&gt;this._disposed = true; // set a instance field &lt;br&gt;&lt;br&gt;Either DoSomeCleanup() needed the this pointer or it didn't.  As long as it needed it then it would be live.  The normal lifetime management will do the job just fine.</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#141569</link><pubDate>Tue, 25 May 2004 18:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:141569</guid><dc:creator>Rico Mariani</dc:creator><description>Another quick followup, I read through Chris's article, his issue was with regard to the *unmanaged* state and the cleanup implications.&lt;br&gt;&lt;br&gt;So I think now I can safely ammend what I've written.&lt;br&gt;&lt;br&gt;Lifetime extension tricks like this one:&lt;br&gt;&lt;br&gt;this._disposed = true; // set a instance field &lt;br&gt;&lt;br&gt;may be useful if you need to force the lifetime an object to be extended so that it for sure doesn't go away before the unmanaged resource it controls.  &lt;br&gt;&lt;br&gt;Important: when I wrote this&lt;br&gt;&lt;br&gt;'The &amp;quot;this&amp;quot; pointer is necessarily live while any member is running'&lt;br&gt;&lt;br&gt;That was wrong (!)&lt;br&gt;&lt;br&gt;&amp;quot;this&amp;quot; is generally reachable for the whole method but it is possible that it might become unreachable and then you could have issues with *unmanaged* state as Chris wrote.  As for managed state, you can't tell the difference which is why in the usual cases it &amp;quot;just works&amp;quot;.</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#143688</link><pubDate>Fri, 28 May 2004 09:52:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:143688</guid><dc:creator>David Levine</dc:creator><description>I've been thinking some about this and I came up with an example of how a constructor can run at the same time as the finalizer.&lt;br&gt;&lt;br&gt;  class MainClass&lt;br&gt;  {&lt;br&gt;    static void Main(string[] args)&lt;br&gt;    {&lt;br&gt;      Console.WriteLine(&amp;quot;Creating object&amp;quot;);&lt;br&gt;      new MainClass(); // don't save the reference&lt;br&gt;      Console.ReadLine();&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    public MainClass()&lt;br&gt;    {&lt;br&gt;      Console.WriteLine(&amp;quot;MainClass.ctor calling collect&amp;quot;);&lt;br&gt;      GC.Collect();&lt;br&gt;      Console.WriteLine(&amp;quot;MainClass.ctor done&amp;quot;);&lt;br&gt;    }&lt;br&gt;    ~MainClass()&lt;br&gt;    {&lt;br&gt;      Console.WriteLine(&amp;quot;MainClass Finalizer&amp;quot;);&lt;br&gt;    }&lt;br&gt;  } //  MainClass&lt;br&gt;&lt;br&gt;A release version produces this output...&lt;br&gt;&lt;br&gt;Creating object&lt;br&gt;MainClass.ctor calling collect&lt;br&gt;MainClass Finalizer&lt;br&gt;MainClass.ctor done&lt;br&gt;&lt;br&gt;This shows that the finalizer ran before the constructor had finished running.&lt;br&gt;&lt;br&gt;A debug build produces...&lt;br&gt;&lt;br&gt;Creating object&lt;br&gt;MainClass.ctor calling collect&lt;br&gt;MainClass.ctor done&lt;br&gt;&lt;br&gt;From what I've read, in a debug build all references are reported as live until the end of a method body (to make debugging easier), so the different outputs makes sense.&lt;br&gt;&lt;br&gt;This is a contrived example but it does demonstrate that unless there is explicit code that keeps an object reference rooted it can be collected regardless of what is actually executing. I don't expect many people to run into problems because of this (it's definitely an edge case) but it does demonstrate that there are subtleties to the GC, and that there may be some differences in behavior between debug and release builds, especially differences related to memory management. &lt;br&gt;&lt;br&gt;This might also affect code written like this...&lt;br&gt;&lt;br&gt;new SomeObject().SomeInstanceMethod();&lt;br&gt;&lt;br&gt;It might also bite people who put their entire application into their constructor (I've seen some lo-o-ong constructors).&lt;br&gt;&lt;br&gt;&lt;br&gt;I've read Chris's revised blogs on lifetime issues, handles, and finalization, and I haven't really processed all of it yet - there's a lot there to digest - but I didn't see anything coming in Whidbey that will invalidate the results here.&lt;br&gt;&lt;br&gt;Thanks for the attention you've given this and for digging into it.&lt;br&gt;</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#143869</link><pubDate>Fri, 28 May 2004 16:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:143869</guid><dc:creator>Rico Mariani</dc:creator><description>This gets curiouser and curiouser.&lt;br&gt;&lt;br&gt;I think there's a problem here but I'm going to have to do more digging to be sure.  I don't think the debug version of the code enters into it.  I can make the debug version exhibit the same behaviour.&lt;br&gt;&lt;br&gt;I changed your test case a little bit to force the issue and to illustrate that storing the reference makes no difference as it is by then far too late.&lt;br&gt;&lt;br&gt;Here is the altered version:&lt;br&gt;&lt;br&gt;using System;&lt;br&gt;&lt;br&gt;  class MainClass&lt;br&gt;  {&lt;br&gt;    static void Main(string[] args)&lt;br&gt;    {&lt;br&gt;      Console.WriteLine(&amp;quot;Creating object&amp;quot;);&lt;br&gt;      MainClass mc = new MainClass(); // this doesn't save you from getting a finalized object (!?!)&lt;br&gt;      Console.ReadLine();&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    public MainClass()&lt;br&gt;    {&lt;br&gt;      Console.WriteLine(&amp;quot;MainClass.ctor calling collect&amp;quot;);&lt;br&gt;      GC.Collect();&lt;br&gt;      Console.ReadLine();&lt;br&gt;      Console.WriteLine(&amp;quot;MainClass.ctor done&amp;quot;);&lt;br&gt;    }&lt;br&gt;    ~MainClass()&lt;br&gt;    {&lt;br&gt;      Console.WriteLine(&amp;quot;MainClass Finalizer&amp;quot;);&lt;br&gt;    }&lt;br&gt;  } //  MainClass&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#143926</link><pubDate>Fri, 28 May 2004 17:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:143926</guid><dc:creator>Rico Mariani</dc:creator><description>I'm telling you blogs are so educational, everyone should have one :)&lt;br&gt;&lt;br&gt;When I saw your example I went into Red Alert Mode because I thought it was hopeless for the poor caller to arrange to always get a valid object in these cases because there is no way for the caller to ensure that a reference is reported for the duration of the .ctor because he has no reference to the object yet.  Lacking that reference it wouldn't matter at all what you did after the .ctor, whether you use the object or not you can't report a reference to it so you'd be doomed to have a chance of a broken finalizable object.&lt;br&gt;&lt;br&gt;The way I thought this worked was that while the .ctor was running the VM reported a reference to the pending object and so an object could never be cleaned up while it was being constructed which would neatly avoid the problem but it would have the undesireable effect of having .ctor invocation being slightly magical in that there is an extra burden there when making such a call.&lt;br&gt;&lt;br&gt;It turns out that the real solution is a little bit different and it neatly matches what we've been seeing.  So, on to the explaination.&lt;br&gt;&lt;br&gt;The reason this hasn't been ruining everyone's life is that contruction of the object happens in two parts.  First the memory is allocated by a helper, this interim state is not visible via normal managed methods etc because always the next thing we do is call the .ctor.  Now what's good about this is that once the allocation is complete the function that invokes the .ctor can report a reference to the as-yet-unconstructed object just like any other object and normally it does exactly that.&lt;br&gt;&lt;br&gt;Here's annotated x86 that is generated in a more normal case where the object lives and why it works.  The two phases are readily visible.  I have changed the example so that the new reference is stored in a static variable which keeps it alive.&lt;br&gt;&lt;br&gt;IN0000: 000000      push    ESI&lt;br&gt;&lt;br&gt;// check for stdio initialization&lt;br&gt;IN0001: 000001      cmp     gword ptr [classVar[0x5b9dc6e8]], 0&lt;br&gt;IN0002: 000008      jne     SHORT G_M001_IG04&lt;br&gt;&lt;br&gt;// initialize console &lt;br&gt;IN0003: 00000A      mov     ECX, 1&lt;br&gt;IN0004: 00000F      call    System.Console.InitializeStdOutError(bool)&lt;br&gt;&lt;br&gt;G_M001_IG04:  &lt;br&gt;&lt;br&gt;// write the 'Creating object' message to the console&lt;br&gt;IN0005: 000014      mov     ECX, gword ptr [classVar[0x5b9dc6e8]]&lt;br&gt;IN0006: 00001A      mov     EDX, gword ptr [08AD1054H]      'Creating object'&lt;br&gt;IN0007: 000020      call    dword ptr [(reloc 0xde30014)]System.IO.TextWriter.WriteLine(ref)&lt;br&gt;&lt;br&gt;//allocate the MainClass object&lt;br&gt;IN0008: 000026      mov     ECX, 0xdd40e10&lt;br&gt;IN0009: 00002B      call    ALLOCATE_MEMORY_HELPER&lt;br&gt;IN0010: 000030      mov     ESI, EAX  // save the new object in ESI&lt;br&gt;&lt;br&gt;// ESI is a reported GC root at this point, preventing disaster&lt;br&gt;&lt;br&gt;// set up for the .ctor call it's just a regular method call like all other methods&lt;br&gt;IN0011: 000032      mov     ECX, ESI&lt;br&gt;IN0012: 000034      call    [MainClass..ctor()]&lt;br&gt;&lt;br&gt;// get static storage for MainClass and write the reference&lt;br&gt;IN0013: 00003A      lea     EDX, bword ptr [classVar[0xdd40d3c]]&lt;br&gt;IN0014: 000040      call    ASSIGN_REF_ESI_HELPER   &lt;br&gt;&lt;br&gt;&lt;br&gt;// wait for a line of input from the console&lt;br&gt;IN0015: 000045      call    System.Console.get_In():ref&lt;br&gt;IN0016: 00004A      mov     ECX, EAX&lt;br&gt;IN0017: 00004C      call    dword ptr [(reloc 0xde3002c)]System.IO.TextReader.ReadLine():ref&lt;br&gt;&lt;br&gt;IN0018: __epilog:&lt;br&gt;        000052      pop     ESI&lt;br&gt;IN0019: 000053      ret     &lt;br&gt;&lt;br&gt;Given the way I thought about this previous to about a half hour ago you can see why I would be alarmed by the behaviour of your example.  My expectation would have been that it would not matter a whit whether I stored the new object in a static variable or a local one because even if I report the static or local since the .ctor hasn't returned yet my variable doesn't hold the actual object reference.  &lt;br&gt;&lt;br&gt;However, because our model is that the allocation is seperate from the construction in the generated code (but not the IL) all you have to do is use the object and everything works out great.  &lt;br&gt;&lt;br&gt;So now there's two cases where things might be wierd. Let be dispose of those.&lt;br&gt;&lt;br&gt;1) My object is finalizable but has only managed state&lt;br&gt;&lt;br&gt;When you construct the object either it is live afterwards or it isn't.  If it is live then there is no chance that it will be finalized while the .ctor is running.  If it is not live then we must have reached a point in the execution where the object is reachable from neither the .ctor nor the calling function.  Since the object is unreachable the caller cannot observe the finalization and neither can the code in the .ctor, everything will look &amp;quot;normal&amp;quot; to all the parties.  Modifications to the object are also necessarily finished so the object will look just as it will when the .ctor is finished so the finalizer also sees everything just as it should be.&lt;br&gt;&lt;br&gt;2) My object is finalizable and is wrapped unmanaged state&lt;br&gt;&lt;br&gt;As discussed earlier in this blog, when writing unmanaged wrapper objects it is important to arrange for the lifetime of the object to exactly match the lifetime of the underlying unmanaged resource.  To accomplish this it is often necessary to use GC.KeepAlive(this).  The .ctor must follow the same rules as every other method.&lt;br&gt;&lt;br&gt;I knew this was subtle but it's even more subtle than I imagined.</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#145414</link><pubDate>Tue, 01 Jun 2004 13:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:145414</guid><dc:creator>David Levine</dc:creator><description>The mental model I've been using is similar to yours...when an object is newed an allocator is called which allocates the memory on the heap, a reference is returned, and then the .ctor is invoked, and that once the memory allocator has returned an object reference it is immediately available for collection. In other words, it starts life with the same degree of aliveness as any other object.&lt;br&gt;&lt;br&gt;I've been looking at the assembly listing and I've a small concern. On line IN009 it calls the memory allocator and on line IN0010 it stores the returned reference in ESI; if a collection was triggered after that point this should be enough to keep the object reachable since ESI is a GC root. However it isn't clear to me what keeps the reference alive if a collection is triggered after IN0009 has been executed but before IN0010 begins. Unless there is a guarantee that the code cannot be interrupted between these two lines then this is a race that eventually we will lose. I wonder if there is a low-level lock that prevents this, or perhaps an implicit KeepAlive that keeps it alive until after the .ctor has run. I am curious.&lt;br&gt;&lt;br&gt;I agree with your conclusions with one minor addition. There may be code in the .ctor and finalizer that is not object instance related but which uses static methods on other classes or calls Win32 APIs. Things might get confusing if both the .ctor and finalizer ran simultaneously and executed conflicting code. In other words, special cases require special care. This is similar to your second conclusion - in this case the object doesn't wrap an unmanaged resource but it does wrap an execution stream, and to prevent problems the lifetime of the object should match the requirements of the execution stream.&lt;br&gt;&lt;br&gt;&lt;br&gt;Another aspect I find interesting (and which relates back to original topic) is that all the examples I've seen have the Dispose method written like this...&lt;br&gt;&lt;br&gt;public void Dispose() // IDisposable implementation&lt;br&gt;{&lt;br&gt;  Dispose(true); // &lt;br&gt;  GC.SuppressFinalize(this);&lt;br&gt;}&lt;br&gt;&lt;br&gt;One question that came up earlier is how could the Finalizer method run at the same time as the Dipose method; we've seen how that is possible. Given the two lines of code above it is also clear that there is a race between the two lines so that the Finalizer may be called after the Dispose method has executed but before the call to SuppressFinalize removes the object from the freachable queue. &lt;br&gt;&lt;br&gt;I prefer reversing the order of the code...&lt;br&gt;&lt;br&gt;GC.SuppressFinalize(this);&lt;br&gt;Dispose(true);&lt;br&gt;&lt;br&gt;This should eliminate the race and also prevent the Dipose method and finalize method from ever executing simultaneously. It might also be less error prone for the average developer because of the implicit elimination of the race and double execution of the dispose method.&lt;br&gt;&lt;br&gt;The only argument I've ever heard for putting them in the other order is that if the Dipose method throws an exception the finalize will still run later because the SuppressFinalize will not have been called. I don't consider this to be a valid reason because I would expect it to be even more likely to throw an exception when invoked a second time from the finalizer; if there is code that needs to exception resilient then it should be in the method body itself. This arrangement might also result in a small performance win by removing the object from the freachable queue a little sooner.&lt;br&gt;&lt;br&gt;Yes, there are some subtleties here! &lt;br&gt;&lt;br&gt;Regards,&lt;br&gt;</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#147967</link><pubDate>Thu, 03 Jun 2004 21:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:147967</guid><dc:creator>Rico Mariani</dc:creator><description>Hmmm, I'm not sure doing the GC.SuppressFinalize(this) first actually removes the race, though it does further restrict the window.  I'm pretty sure the race is still there.  I think the real solution to that problem is to use GC.KeepAlive(this) for those rare cases where there is a lifetime problem.&lt;br&gt;&lt;br&gt;So the reason for doing GC.SuppressFinalize(this) first or last then should be at what point you feel it's safe for the finalizer to not run.  I think our guidance has been that it's generally safer to let the finalizer run until you're sure cleanup is complete.  Which argues for doing the supress last.&lt;br&gt;&lt;br&gt;When you consider the possibility that there could be derived classes in the picture which want to Dispose their own state and then call the base class Dispose method you rapidly conclude that it must be the first class that introduces Dispose which must do the supress and since it is last to be call no semantic other than suppress last has much hope of being achieved.&lt;br&gt;&lt;br&gt;Well, that's how I see it from here anyway :)&lt;br&gt;</description></item><item><title>Two quick hrefs</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#148040</link><pubDate>Fri, 04 Jun 2004 01:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:148040</guid><dc:creator>Rico Mariani's WebLog</dc:creator><description /></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#150714</link><pubDate>Tue, 08 Jun 2004 09:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:150714</guid><dc:creator>Jonathan Perret</dc:creator><description>I don't think there's a problem with putting GC.SuppressFinalize(this) at the end of the method.&lt;br&gt;&lt;br&gt;GC.SuppressFinalize(this) implies GC.KeepAlive(this) (AFAIK GC.KeepAlive is just an empty method with a convenient name).&lt;br&gt;&lt;br&gt;In other words, there is no way the object can be eligible for finalization before execution reaches GC.SuppressFinalize(this), since this call requires access to &amp;quot;this&amp;quot; and therefore functions as an &amp;quot;anchor&amp;quot; that keeps it alive until that point.&lt;br&gt;&lt;br&gt;A related point regarding Rico's &amp;quot;modified&amp;quot; example with the line :&lt;br&gt;&lt;br&gt;MainClass mc = new MainClass(); // this doesn't save you from getting a finalized object (!?!) &lt;br&gt;&lt;br&gt;As far as I understand, just adding &amp;quot;MainClass mc=&amp;quot; in front of the allocation does not by itself change anything in the semantics of the program as passed by the compiler to the GC.&lt;br&gt;As long as you don't refer to 'mc' further, the variable can be safely removed.&lt;br&gt;&lt;br&gt;Chris Brumme's weblog is indeed a great read to understand this kind of problems...&lt;br&gt;&lt;br&gt;</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#155723</link><pubDate>Tue, 15 Jun 2004 02:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:155723</guid><dc:creator>Akshay Kumar</dc:creator><description>What happens if we call Dispose multiple times on an object.&lt;br&gt;I tried it on SqlConnection and no exception etc was thrown.&lt;br&gt;the reason I ask is b'cos I have written a wrapper for an object which provides dispose method and expose that object as a property.&lt;br&gt;Now developer can call dispose method on underlying object.&lt;br&gt;Also I implemented Dispose method and finalizer, so that if developer forgets to call dispose method on underlying methods then it gets cleaned up.&lt;br&gt;So what are the performance implications.</description></item><item><title>re: A few questions and answers about using IDisposable</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#172758</link><pubDate>Sun, 04 Jul 2004 10:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:172758</guid><dc:creator>Rico Mariani's WebLog </dc:creator><description>Two quick hrefs </description></item><item><title>Disposal Anxiety</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#253667</link><pubDate>Mon, 08 Nov 2004 02:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:253667</guid><dc:creator>K. Scott Allen's Blog</dc:creator><description /></item><item><title>Disposal Anxiety</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#253672</link><pubDate>Mon, 08 Nov 2004 02:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:253672</guid><dc:creator>K. Scott Allen's Blog</dc:creator><description /></item><item><title>re: When to call GC.Collect()</title><link>http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx#272378</link><pubDate>Tue, 30 Nov 2004 20:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:272378</guid><dc:creator>Rico Mariani's Performance Tidbits</dc:creator><description /></item></channel></rss>