title: How to stop an object (and everything inside it) from being finalized?
body: <p>In my two-week long quest to solve a problem:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/18020861/how-to-get-notified-before-static-variables-are-finalized">How to get notified before static variables are finalized</a></li>
  <li><a href="https://stackoverflow.com/questions/18033100/unload-event-for-the-default-application-domain">Unload event for the default Application Domain?</a></li>
  <li><a href="https://stackoverflow.com/questions/18153342/profiling-asp-net-applications-over-the-long-term">Profiling ASP.net applications over the long term?</a></li>
  </ul>
  
  <p>the fundamental problem is the <em>garbage collector</em>. My object's <em>Finalizer</em> would have been the ideal time to react when the object is about to be freed (i.e. to have its resources reclaimed). The problem with the .NET garbage collection system is that by the time <em>my</em> finalizer is called, it's entirely likely that other objects i own have already been finalized.</p>
  
  <p>The problem would be trivial to solve if i were interoping with <em>native</em> class objects. The garbage collector is unable to free those objects behind my back (and without my permission). So by the time my managed object's finalizer is called, i <strong>know</strong> that my internal state is still valid.</p>
  
  <p>What i need is a way to tell the garbage collector to <strong>keep your hands off</strong>.</p>
  
  <p>Is there a ways to prevent an object from being finalized?</p>
  
  <h2>For example</h2>
  
  <p>For example, the following code is buggy, because the finalizer mistakenly things that the private <code>_values</code> object still exists. In reality it is likely already finalized out from under me:</p>
  
  <pre><code>class Sqm
  {
     private List&lt;Value&gt; _values = new List&lt;Value&gt;();
  
     //finalizer
     public ~Sqm()
     {
         Shutdown();
     }
  
     protected void Shutdown()
     {
        foreach (var value in _values)  //&lt;-- crash; _values no longer exists
           SaveValueToHardDrive(value); //&lt;-- crash; value no longer exists
     }
  }
  </code></pre>
  
  <p>What i need is a way to tell the garbage collector <strong><em>not</em></strong> to finalize that list object, or any of the objects inside it:</p>
  
  <pre><code>class Sqm
  {
     private List&lt;Value&gt; _values = new List&lt;Value&gt;();
  
     //constructor
     public Sqm()
     {
        GC.LetMeManuallyFinalize(_values);
     }
  
     //finalizer
     public ~Sqm()
     {
         Shutdown();
         GC.ManuallyFinalize(_values);
     }
  
     protected void Shutdown()
     {
        foreach (var value in _values) 
           SaveValueToHardDrive(value);
     }
  }
  </code></pre>
  
  <p>That has two possible problems:</p>
  
  <ul>
  <li>there is no <code>GC.ManuallyFinalize</code> method</li>
  <li><p>it might suppress freeing the <code>_values</code> list itself, but the objects it references would likely still be finalized behind my back:</p>
  
  <pre><code>  protected void Shutdown()
    {
       foreach (var value in _values) 
          SaveValueToHardDrive(value); //&lt;---crash, contained object already finalized
    }
  </code></pre></li>
  </ul>
  
  <p>So now i need to ensure that the objects, as they are added to the list, are also excluded from finalization:</p>
  
  <pre><code>public void AddSample(String name, Int64 value)
  {
      Entry entry = GetEntryByName(name);
      if (entry == null)
      {
         entry = new Entry();
         GC.LetMeManuallyFinalize(entry);
      }
  
      entry.Count += 1;
      entry.Sum += value;
      entry.Average = entry.Sum / entry.Count;
  }
  
  //finalizer
  public ~Sqm()
  { 
     foreach (var value in _values)
        GC.ManuallyFinalize(value);
  
     GC.ManuallyFinalize(_values);      
  }
  </code></pre>
  
  <p>That probably has the problem that while <code>Entry</code> has no other internal objects, i don't know about <code>List&lt;T&gt;</code>. And the garbage collector might perform an unwanted labotomy on <code>_values</code> even though <code>_values</code> itself hasn't been finalized.</p>
  
  <h1>Use GCAlloc.Alloc()</h1>
  
  <p>@MatthewWatson had an excellent idea. i think it would be useful to point out why it's wrong. Use <code>GCAlloc.Alloc</code> to hold a reference to the object. Then you use can access it during your finalizer:</p>
  
  <pre><code>public Sqm()
  {
     private List&lt;Value&gt; _values = new List&lt;Value&gt;();
     private GCHandle _valuesHandle; //handle to keep _values alive
  
     //constructor
     Sqm()
     {
        //prevent _values from being finalized
        _valuesHandle = GCAlloc.Alloc(_values); 
     }
  
     //finalizer
     ~Sqm()
     {
        try
        {
           Shutdown(_values); //Safe, right? RIGHT? _values couldn't have been finalized
        } 
        finally
        {
           _valuesHandle.Free();
        }
     }
  
     private void Shutdown(List&lt;Values&gt; values)
     {
        foreach (var value in values)
        {
           //The list itself might not have been finalized
           //But objects used internally to Microsoft's List&lt;T&gt; class have been finalized
           //and objects in the list itself were already finalized
           SaveValueToHardDrive(value); //&lt;--BAD: values inside list were already finalized
        }
     }
  }
  </code></pre>
  
  <p><strong>Note:</strong> It also probably fails because of the pseudo-documented behavior. From <a href="http://blogs.msdn.com/b/clyon/archive/2005/03/18/398795.aspx" rel="nofollow noreferrer">The Truth About GCHandles</a>:</p>
  
  <blockquote>
    <p>When you create a new <code>GCHandle</code>, a new entry in the AppDomain's handle table is created. This entry is kept until the handle is freed (via <code>GCHandle.Free()</code>) <strong>or the AppDomain is unloaded</strong>.</p>
  </blockquote>
  
  <p>Emphasis mine.</p>
  
  <p>So that's right out. i need to tell the garbage collector</p>
  
  <blockquote>
    <p>Do not finalize this object (<strong>and everything inside it</strong>)</p>
  </blockquote>
  
  <p>The tricky part is the internal private members of classes i do not own; even an object still referenced by <code>GCAlloc</code> will still have objects it depends on finalized behind it's back.</p>
  
  <h1>Sample Usage</h1>
  
  <pre><code>public static Foo
  {
     public static Sqm = new Sqm();
  }
  
  Foo.Sqm.AddSample("QueryCustomerInfo", stopwatch.TotalMicroseconds);
  </code></pre>