Archive for February, 2006

The Worst Possible Way to Handle Exceptions

The worst possible way to "handle" exceptions is to show the user a message box with __FILE__ as the text. This is extremely poor form.

Intel VTune error dialog

Apparently, Intel did not get the memo. Worse, this happens as many as ten times when I open Visual Studio. Why do I feel like I was mistakenly given a debug build of VTune?

A Minor Victory for Secularism in Lower Manhattan

I'm sure there are those who will find irony in this post's title, but sometimes we have to fight our battles where we find them. Roughly a month ago, I found this statue assaulting my aesthetic faculties at the corner of Water Street and Old Slip.

Joseph Smith, the founder of Mormonism. Somehow, this monstrosity cost $300,000.

Joseph Smith (of "Latter Day Saint" fame) has a loose historical affiliation with what is now the Financial District, or so I am told. And that much is fine. Despite my overwhelming distaste for the sculpture, I wouldn't be one to complain if it were merely there to point out that "Joe slept here." Fair enough.

Unfortunately, the display really went for the evangelical gusto. There is of course the bravado with which it was erected:

Bless those who come upon this monument, who do not yet know Joseph, with a desire to learn more concerning Thee and Thy Gospel restored through him. May this statue serve in spreading the message of Thy Gospel to growing numbers of local inhabitants and to visitors to this great city. [source]

Which, sickly as it may be, is perhaps not yet in violation of any laws. The inscription on the statue, however, does cross the line. This is the message I sent to the director of the parks department.

I had all but given up on this crusade (pardon the term) when I received a letter dated February the tenth tonight. I'll not reproduce all of it, since I don't want to expose the poor Parks worker to any undeserved criticism and because he expends several paragraphs nonsensically flailing straw men who apparently want to ban sectarian weddings in public parks. This is the important bit:

To that, I sent this in reply.

An outstanding and unexpected turn of events.

A Real Head-Scratcher Courtesy The CLR And Office Teams

"Why the hell is this application insisting on loading an old version of the CLR?" I'm guessing that's what you're asking yourself if you've gotten here through your search engine of choice. Well, relax. I'm about to explain.

It is reasonably well-known that there are .config file settings that can force an application to load a specific CLR version. It is also possible to write unmanaged code using the hosting API's like CorBindToRuntimeEx to bind to a specific version. I'm not talking about either of these scenarios.

There is a set of undocumented (as far as I know) registry keys that can override either of these vectors. They are located here:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy\AppPatch\v2.0.50727.00000

If you take a look at this key on your own machine, you'll probably see a handful of applications listed.

The root of the Microsoft Office .NET Framework version bug

Applications can specify a target version of the framework that will be loaded into the process, even if there is no .config file present, and even if you write some C++ to call CorBindToCurrentRuntime. Mscoree will simply report that the current runtime is 1.1.4322, even if the user has 2.0 installed on their machine. This is, I suppose, superfically similar to the strategy used in the Image File Execution Options built into NT.

I can see where this would be handy–presumably Microsoft has a handful of .NET 1.1 apps in the wild that showed bugs against 2.0, and it's not exactly practical or foolproof to try to drop a .config file on those apps when installing the framework (naturally, somebody can just install the application after the framework, then be puzzled as to why it isn't working).

Good solution, right? It's a shame they fouled it up.

Notice that Word and Excel are both listed as special applications on my machine. I have these values on my laptop:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy\ AppPatch\v2.0.50727.00000\excel.exe\{2CCAA9FE-6884-4AF2-99DD-5217B94115DF}]
"Minimum File Version Number"="11.0.0.0"
"Maximum File Version Number"="11.0.9999.9999"
"Target Version"="v1.1.4322"

It appears as though the someone is trying to force a relatively older build of Excel/Word 2003 to load v1.1. Fair enough, the Excel build on my machine is up to 11.6 at this point. Unfortunately, those developers failed miserably in the attempt. Every single other application listed under AppPatch in my registry looks like this:

"Minimum File Version"="11.0.0.0"
"Maximum File Version"="11.0.9999.9999"
"Target Version"="v1.1.4322"

When the version filter isn't specified (or actually in this case, miswritten as "Minimum/Maximum File Version Number" instead of "Minimum/Maximum File Version"), all versions of the executable will load the target version. So these keys effectively break 2.0 addins for all versions of Word and Excel.

There is an update available that fixes this issue, here. The KB article that accompanies it doesn't really explain what the issue is, which is why I've summarized it here. Office update is not exactly an automatic affair like its Windows counterpart, so this bug makes it essentially impossible to write a fault-free Office addin that targets 2.0 and does not hack up the user's registry upon installation. I can't say I advocate doing that, but I would understand if you did. As for myself, I am most likely going to target 1.1 much longer than I had hoped would be necessary.

Generic and Threadsafe Singleton Implementation

I googled around, and couldn't find a generic singleton implementation that was 1) correct and 2) met all of my needs. This is a clever approach, but unfortunately it is limited to objects that are created by calls to constructors.

So I went ahead and wrote the singleton generic that I fully expect to be included in the next BCL. (Not really. It's completely straightforward. However, the Steelers won the super bowl yesterday, so I'm not really in a modest mood.)

I started out defining a class factory type, which is responsible for creating the an instance in a purposefully vague way. I also wrote the default version which just calls new().

ClassFactory object model

/// <summary>
/// Interface for objects that create instances of
/// another type.
/// </summary>
public interface IClassFactory<T> where T : class
{
        T CreateInstance();
}

/// <summary>
/// A default <see cref="IClassFactory"/> implementation,
/// which uses a parameterless constructor to create the
/// instance.
/// </summary>
public class DefaultClassFactory<T> : IClassFactory<T>
        where T : class, new()
{
        public T CreateInstance()
        {
                return new T();
        }
}

From there, I went for the slam dunk in writing both a singleton class with a class factory and a default version that doesn't require one.

Singleton object model

/// <summary>
/// A base (or helper) singleton class. Defines the
/// singleton instance.
/// </summary>
/// <typeparam name="T">
/// The type of the singleton object.
/// </typeparam>
/// <typeparam name="class_factory">
/// The type of the class factory to use to create an
/// instance of type <typeparamref name="T"/>.
/// </typeparam>
public class Singleton<T, class_factory>
    where T : class
    where class_factory : IClassFactory<T>, new()
{
    private static object _sync = new object();
    private static T _default;

    /// <summary>
    /// Gets the singleton instance.
    /// </summary>
    public static T Default
    {
        get
        {
            EnsureDefault();
            return _default;
        }
    }

    /// <summary>
    /// Ensures that the singleton has been created.
    /// </summary>
    private static void EnsureDefault()
    {
        if (_default == null)
        {
            lock (_sync)
            {
                if (_default == null)
                {
                     CreateDefault();
                }
             }
        }
    }

    /// <summary>
    /// Uses the class factory to create the instance.
    /// </summary>
    private static void CreateDefault()
    {
        class_factory cf = new class_factory();
        T value = cf.CreateInstance();

        // This ensures that writes in the creation of
        // the default instance won't be shuffled beyond
        // the write to _default. Only matters on multiproc
        // machines where the hardware allows this. Does
        // nothing on an x86.
        Thread.MemoryBarrier();
        _default = value;
    }
}

/// <summary>
/// A basic singleton type that can be used with objects
/// that are created with a parameterless constructor.
/// </summary>
public class Singleton<T> :
    Singleton<T, DefaultClassFactory<T>>
    where T : class, new()
{
}

(For more on why I added that call to Thread.MemoryBarrier(), see this writeup.)

Here's a really simple example that does not take advantage of the customizability:

public class Foo : Singleton<Foo>
{
}

If you can't use Singleton as a base class, you have to write a little more code.

public class Foo : Bar
{
    public static Foo Default
    {
        get { return Singleton<Foo>.Default; }
    }
}

Thus Ends the Great Adsense Experiment

I install Adblock on all my machines, so I wasn't seeing any of the ads on my own site. I had thought they were all going to be hilariously off-topic (one that stood out was some guy named "Dan Poynter" plugging his small business), but apparently not. It didn't occur to me that if I wrote articles decrying pet psychics that Google would plaster ads for palm readings all over my site, but in retrospect that was obviously the only possible result. It turns out that the money isn't worth looking like an idiot.