More info on 'using' and resource management

Joe Duffy (PM on the CLR team) posted to my blog about the whole using/resource management subject.  Being an cool and froody guy (who i may or may not have ever met) he linked back to a great post of his own on the subject *and* included even more information on the subject.  I'm going to repost his post here (since formatting of comments sucks on Community Server) so you can read it, and i also recommend you read his blog since it's chock full of good content.

--- (the following is written by Joe) ---

I cover this in fair detail in my article, which I was happy to notice somebody already linked to!

This is a problem we really want to solve in Orcas. I noted a couple possible solutions at the bottom of the article. I had a few other speculations, but after conversations w/ Chris Brumme, I realized most of them were crap and we'd never recommend people write their code that way (nevermind have C# spit the code).

For example,

 ExpressionType temp = null; 
try { 
    try {
    } finally {
        temp = /*async-exception gets held up if triggered here*/ expression;
    } 
    /* ...and actually throws here */ 
    statement 
} finally { 
    if (temp != null) { 
        ((IDisposable)temp).Dispose(); 
    } 
}

will ensure that an async exception won't get raised, since we hold off on processing them during finally block execution. We also don't execute them while you're in a CER, running some opaque unmanaged code, and a few other corner scenarios. But holding up an async abort is a pretty rude thing to do, especially if you intend to block inside of it.

Further, you could imagine a class like

 static class ReliableFactory { 
    public static void New<T>(out T created) where T : new() { 
        try {
        } finally { 
            created = new T(); 
        } 
    } 
} 

which would enable you to write

 ExpressionType temp = null; 
try { 
    ReliableFactory.New<ExpressionType>(out temp); 
    /* similar to above, an async exception won't prevent the out assignment to temp */ 
    statement 
} finally { 
    if (temp != null) { 
        ((IDisposable)temp).Dispose(); 
    } 
} 

But this is fairly hokey.

I really hope we solve this problem in Orcas. But there's quite a bit to do with Dispose that needs a fixin', too. :)