2011-02-20

SynchronizationContext Odds and Ends

During my many adventures with SynchronizationContext, I ran into two rather interesting corner cases. Originally, these appeared as footnotes in my article, but they were among the first things that I cut.

Both of these corner cases deal with a "missing" SynchronizationContext; that is, SynchronizationContext.Current is null when it shouldn't be. In this case, the default SynchronizationContext is used, which invokes all of its callbacks on the ThreadPool thread. One common symptom of this problem is that BackgroundWorker.RunWorkerCompleted gets a cross-thread exception.

Missing SynchronizationContext in Office Add-Ins

I ran into this issue on the MSDN forums. Apparently, Microsoft Office add-ins do not have a SynchronizationContext installed when they are invoked. This appears to be a simple oversight, and is fixed by calling SynchronizationContext.SetSynchronizationContext, passing a new WindowsFormsSynchronizationContext().

The MSDN forums have several other threads dealing with the same issue, phrased several different ways.

Missing SynchronizationContext in (old versions of) Windows Forms before Show

Less than a year ago, Windows Forms would only install the WindowsFormsSynchronizationContext when the first Win32 window handle for that thread was created. In particular, SynchronizationContext.Current was null through the main form's constructor and Load event. It would be set, however, by the time the Show event was invoked. One common workaround was to force the creation of the Win32 window handle (by reading the Handle property), which installed the proper SynchronizationContext as a side-effect.

Fortunately, that hack is no longer necessary. Sometime in the last year, Microsoft released an update that fixes that issue all the way back to .NET 2.0 Windows Forms projects. I'm not sure which update that was.

2011-02-11

Option Parsing: Introduction

Last week, Nito.KitchenSink.OptionParsing was released on NuGet. This is a command-line option parsing library that I've used for years. Since my day job currently consists of re-architecting firmware, I figured I'd write a few posts on the Nito.KitchenSink NuGet (mini-)libraries.

First, here's a little sample program to show how the option parsing library is used:

using System;
using System.IO;
using System.Reflection;

using Nito.KitchenSink.OptionParsing;

class Program
{
    // Define the options
    private sealed class MyOptions : OptionArgumentsBase
    {
        [Option("level", 'l')]
        public int? Level { get; set; }

        public static int Usage()
        {
            Console.Error.WriteLine("Usage: myprog [OPTIONS]...");
            Console.Error.WriteLine("  -l, --level=LEVEL   Sets the level at which to operate.");
            return -1;
        }
    }

    static int Main()
    {
        try
        {
            // Parse the options.
            var options = OptionParser.Parse<MyOptions>();

            // Do the requested operation.
            if (options.Level != null)
                Console.WriteLine("Level: " + options.Level);
            return 0;
        }
        catch (OptionParsingException ex)
        {
            // Handle usage errors.
            Console.Error.WriteLine(ex.Message);
            return MyOptions.Usage();
        }
        catch (Exception ex)
        {
            // Handle operation errors.
            Console.Error.WriteLine(ex);
            return -1;
        }
    }
}

The sample program above only takes a single option: a "level". First, I define the option in the MyOptions class, along with a static Usage to display command-line usage.

The actual program just parses its command-line options and then displays the level if it was specified. The error handling code distinguishes between usage errors and operating errors (all option parsing errors derive from OptionParsingException).

Even though the sample program only includes a single option, a lot of variety is allowed by the option parsing library:

> myprog

> myprog -l 3
Level: 3

> myprog --level 3
Level: 3

> myprog /level 3
Level: 3

> myprog /l 3
Level: 3

By default, the Nito.KitchenSink.OptionParsing library allows short options (with a single dash), long options (with a double dash), and short or long options (with a forward slash).

In addition, the option argument can be separated by whitespace (as in the examples above), a full colon, or an equals sign:

> myprog /l:3
Level: 3

> myprog /level=3
Level: 3

> myprog -l=3
Level: 3

The Nito.KitchenSink.OptionParsing library also handles common errors, and tries to give meaningful error messages:

> myprog wha?
Unknown parameter  wha?
Usage: myprog [OPTIONS]...
  -l, --level=LEVEL   Sets the level at which to operate.

> myprog -bad
Unknown option  b  in parameter  -bad
Usage: myprog [OPTIONS]...
  -l, --level=LEVEL   Sets the level at which to operate.

> myprog /bad
Unknown option  bad  in parameter  /bad
Usage: myprog [OPTIONS]...
  -l, --level=LEVEL   Sets the level at which to operate.

> myprog -l
Missing argument for option  level
Usage: myprog [OPTIONS]...
  -l, --level=LEVEL   Sets the level at which to operate.

> myprog -l null
Could not parse  null  as Int32
Usage: myprog [OPTIONS]...
  -l, --level=LEVEL   Sets the level at which to operate.

Option parsing is case sensitive by default:

> myprog /Level:3
Unknown option  Level  in parameter  /Level:3
Usage: myprog [OPTIONS]...
  -l, --level=LEVEL   Sets the level at which to operate.

There's actually a lot of work being done in the single-line OptionParser.Parse<MyOptions>()! And this post is just scratching the surface; the Nito.KitchenSink.OptionParsing library is all about flexibility and extensibility.

2011-02-03

NuGet Packages for Nito.KitchenSink

Ever since NuGet was released, I've been working on changing the design of the Nito.KitchenSink library. As a CodePlex project, it's acted as a "catch-all" for reusable code that wasn't large enough for its own project. NuGet provides a simple way to handle many small packages.

I've been taking the more stable parts of Nito.KitchenSink, reviewing the design of each type, completing the XML documentation, and instrumenting them with Code Contracts. Tonight, the first twelve packages were published to the official NuGet feed. They all start with "Nito.KitchenSink".

The KitchenSink project will continue, but this is the first step of making it into a "library collection" rather than a single library. Eventually, the huge ILMerged binary will be replaced by many independent NuGet packages and a single, smaller binary.

2011-02-01

MSDN Article on SynchronizationContext Published

My first article in MSDN - It's All About the SynchronizationContext - has been published in the February 2011 issue. Check it out and let me know what you think!

Kudos to my wife and children for putting up with me being even busier than normal, and of course to Jesus Christ for - well, everything!