Now I'm confused (C++/CLI destructors)

So here I am, writing a piece about how the C++/CLI destructor and finalizer stuff could have been a bit neater and I put together some sample code to demonstrate my point and it doesn’t do what the docs I mentioned yesterday suggest that it should do…

Given this example class….

ref class Example
{
   public :
   
      Example(
         bool throws)
         : m_count(s_count++),
            m_string(gcnew String("MyString"))
      {
         Console::WriteLine(m_count + " - Example(throws = " + throws + ")");

         if (throws)
         {
            throw "Thrown";
         }
      }
   
      Example()
         : m_count(s_count++),
            m_string(gcnew String("MyString"))
      {
         Console::WriteLine(m_count + " - Example");
      }
   
      ~Example()
      {
         Console::WriteLine(m_count + " - ~Example");

         delete m_string;
	
         this->!Example();            
      }

      !Example()
      {
         Console::WriteLine(m_count + " - !Example");
      }

   private :

      const int m_count;

      String ^m_string;

      static int s_count = 0;
};

And the following test code…

int main(array<System::String> ^args)
{
   try
   {
      Example example(true);
   }
   catch(...)
   {
      Console::WriteLine("Caught");
   }
   
   try
   {
      Example ^example = gcnew Example(true);
   }
   catch(...)
   {
      Console::WriteLine("Caught");
   }
    
   return 0;
}

I was expecting, based on these docs from MSDN, that the output would be something like this:

0 - Example
0 - ~Example
0 - !Example
Caught
1 - Example
Caught
1 - !Example

But, instead, I actually get this:

0 - Example
Caught
1 - Example
Caught
1 - !Example
0 - !Example

That is, the destructor for the stack based object isn’t called (as the docs seem to imply it would be), but the finalizers are when the objects are garbage collected…

Am I being dense here?