Servergeek
Mickey Williams' weblog


Powered by Blogger Pro™

Monday, February 09, 2004

Some Sharp Edges Around the C# using Statement


Interesting (and fun) things happen when you teach C# to smart people. I got this blog entry from a discussion at the end of one of my recent C#/Framework classes. Given a minimal disposable type P:

class P: IDisposable 
{ 
        ~P() 
        { 
                Console.WriteLine("Finalized"); 
        } 
        public void Dispose() 
        { 
                GC.SuppressFinalize(this); 
                Console.WriteLine("Disposed"); 
        } 
} 

Leaving aside the wisdom of Console.WriteLine inside a finalizer, does the following code compile? If it does, what is the result?

using(P p = new P()) 
{ 
        p = null; 
        GC.Collect(2); 
        System.Threading.Thread.Sleep(500); 
} 

Skipping ahead (due to lack of interaction via the blog) I'll just tell you that it doesn't compile - the C# specification clearly indicates that when a local variable is declared inside a using statement, the variable is read-only, and can't be assigned to a ref or out parameter (see 16.1).

However, the following code is expected to compile. Why? And what is your expected result (answer below the code)?

P p; 
using(p = new P()) 
{ 
        p = null; 
        GC.Collect(2); 
        System.Threading.Thread.Sleep(500); 
} 

The result is:

Disposed

At first glance this is an interesting result, as the instant assumption is that the object referenced by p has no references, and is elligble for finalization and collection. However, these two examples illustrate how the using statement interacts with ownership and lifetime expectations.

Although a declaration inside a using statement implies a specific lifetime, aquiring a resource and binding it to an existing variable has somewhat muddier semantics. Clearly the variable has had a lifetime before marriage the using block, and may be available for use after the using block. In such a case, the variable should not be read-only; however its aquired resource must be disposed of when execution flows out of the using block. Note: although this is an interesting exercise for exploring using/GC side-effects, if you truly have a disposable instance, you should be calling p.Dispose() prior to setting the reference to null. However, as I am currently wearing my anal-retentive academic hat, such practical applications are not necesarily the moving force here.

The code emitted by the compiler creates an alias reference for p (hereafter pp), and the emitted IL is actually the moral equivalent of:

P p = new P();
P pp = p;
try 
{ 
        p = null; 
        GC.Collect(2); 
        System.Threading.Thread.Sleep(500); 
}
finally
{
	if(pp != null)
		pp.Dispose();
} 

This follows the looser semantics made necessary by the separation of variable declaration and resource aquisition. It also neatly handles poorly-advised alias cases, such as:

using(p = new P()) 
{ 
	a = p;
	if(SomeOddCase)
		c = a;
        p = null; 
} 

However, this behavior does have side-effects, as the compiler is forced to create an additional reference with its own lifetime. Keep this in mind if you have the need to aquire resources at the beginning of long-lived using blocks.

How Clean is the Future of SOAP?


The latest issue of Communications, the magazine sent to the general membership of the ACM includes, "How Clean is the Future of SOAP?". Anyone that has encountered me in the last few days has, no doubt, noticed the steam pouring from my ears as a direct result of reading this article. Nay, not only reading, but finishing. Not even that - re-reading because I was sure that I had missed some nuance, some fundamental point that would move the article from hatchet-job to article worthy of being published in Communications. This is an article of incredibly poor quality that discusses the coming disaster where SOAP services, which by design have no security (I know, wait for it) open up networks to unauthorized access, and cause system administrators to close SOAP access across port 80. I am not making this up.

Solutions to the "problem" raised in the article have existed for years now. Although the obvious, early solutions were endpoint specific, the ability to secure a web service has existed for those skilled in the art for quite some time. In my opnion, the late work done in standards bodies has not focused so much on narrow how-to questions, as much as ensuring interoperability and policy enforcement and discoverability. How anyone can write an article on web service security issues and manage to completely ignore the efforts of both WS-I and OASIS (not to mention vendor-specific solutions) is just beyond my comprehension, especially as security implementations from IBM and Microsoft seem to pop out in regular intervals.

I know that Communications is more of a political tome than a peer-reviewed journal, but this article is just an embarrassment, both to the ACM (which proudly claims to be "The First Society in Computing") and the Author's institution. The article includes only four end-notes, all of them ancient. The most recent appears to be two years old, an eternity in the web services world. Two years for a web service spec is 50 people-years. And what research is indicated by the footnotes? Judge for yourself:

  1. Bequet, H. Automate SOAP calls in Java with the proxy pattern. JavaPro, (Jan. 2002).
  2. Newcomer, E. Understanding Web Services: XML, WSDL, SOAP, and UDDI. Addison Wesley Professional, 2002.
  3. Skonnard, A. SOAP: The Simple Object Access Protocol. Technical report, Microsoft, 2001; www.microsoft.com/mind/0100/soap/soap.asp.
  4. WWW Consortium. HTTP: Hypertext Transfer Protocol. Technical report, 2001.

The MIND article from January 2000. How old is that? To put this in perspective, it was six full months before the public release of the .NET preview. The HTTP specification is mainly irrelevant to the discussion in the article. The other references are out-of-date, not best evidence, or both.

As someone that has both academic and practical interests in computing (and correctness in distributed systems in particular), I've enjoyed the tension involved in trying to keep feet in both camps. But I have no idea what to make of this article. It is myopic, poorly researched, factually incorrect, and has a hysterical chicken-little-like tone that is not appropriate for Communications. This is a very sad state of affairs in my opinion.


Home