Monday 13 October 2014

Thread-Safe Singleton Construction

Using the Singleton design pattern it is a common technique to ensure only one instance of a class exists during runtime:

class NonThreadSafeSingleton
{
 static NonThreadSafeSingleton instance;

 public static NonThreadSafeSingleton Instance
 {
  get
  {
   if (instance == null)
    instance = new NonThreadSafeSingleton();
   return instance;
  }
 }
}

The above implementation of the Singleton pattern may work, but it doesn't make it safe to use between multiple threads.  If multiple threads were to access the above Singleton implementation we may experience the following sequence as executed by the runtime:

Order Thread 1 Thread 2
1 if (instance == null)
2 if (instance == null)
3 instance = new NonThreadSafeSingleton();
4 instance = new NonThreadSafeSingleton();
5 return instance;
6 return instance;

As you can see in the order of execution the NonThreadSafeSingleton class is instantiated twice due to a race-condition.  When in reality our desired execution is as follows:

Order Thread 1 Thread 2
1 if (instance == null)
2 instance = new NonThreadSafeSingleton();
3 return instance;
4 return instance;

If we're going to make this thread-safe one approach in .NET 2.0 would be to use an exclusive lock:

class ThreadSafeSingletonWithLock
{
 static ThreadSafeSingletonWithLock instance;
 static object locker = new Object();

 public static ThreadSafeSingletonWithLock Instance
 {
  get
  {
   lock (locker)
   {
    if (instance == null)
     instance = new ThreadSafeSingletonWithLock();
   }
   return instance;
  }
 }
}

But looking at the sequence of execution we now run into the problem of a lock always being acquired even if the instance is already constructed (executions 1 and 6 listed below):

Order Thread 1 Thread 2
1 lock (locker)
2 if (instance == null)
3 instance = new ThreadSafeSingletonWithLock();
4 return instance;
5 lock (locker)
6 return instance;

This causes an additional overhead which isn't desired.  It is actually possible to achieve the same requirement of synchronising the object construction whilst minimising the amount of locking required:

class ThreadSafeSingletonWithDoubleCheckLock
{
 static ThreadSafeSingletonWithDoubleCheckLock instance;
 static object locker = new Object();

 public static ThreadSafeSingletonWithDoubleCheckLock Instance
 {
  get
  {
   if (instance == null)
   {
    lock (locker)
    {
     if (instance == null)
      instance = new ThreadSafeSingletonWithDoubleCheckLock();
    }
   }
   return instance;
  }
 }
}

It is still possible for two threads to "lock" during object construction, although if  the object construction is quick the likelihood of this condition occurring is minimised.  Any additional instance retrievals after instantiation are done outside of the lock providing an improvement during runtime.  Although the above implementation of the thread-safe Singleton pattern is better than the prior implementation, it kind of feels a bit messy having to implement the condition to check if the instance is equal to null two times, an inexperienced developer may think this is unnecessary and run the risk of the line of code being removed.

An even better implementation is provided in .NET 4.0 BCL with Lazy<T>.  This allows a single instance of a class to be instantiated upon request in a thread-safe way.   An example of it's usage is shown below:

class ThreadSafeLazySingleton
{
 readonly static Lazy<ThreadSafeLazySingleton> instance = new Lazy<ThreadSafeLazySingleton>(() => new ThreadSafeLazySingleton());

 private ThreadSafeLazySingleton(){}

 public static ThreadSafeLazySingleton Instance
 {
  get { return instance.Value; }
 }
}

The Lazy<T> overloaded constructors provide performance options during construction.  For example, if the instance isn't going to be used between multiple threads then it is possible to define the Lazy instance as non-thread safe to ensure the highest possible performance.

By using the Lazy class we achieve the following:
  1. Encapsulating the locking mechanism: As the synchronisation of instantiation is internal to the Lazy<T> class any future optimisations done by the .NET team should not effect the usage of this class unless they intend of implementing a breaking-change;
  2. Allows the singleton instance to be used in a thread-safe environment;
  3. Gracefully encapsulates the double-check locking inside the class without having the developer to implement this themselves
The private constructor in the examples above have been omitted for brevity purposes.

Wednesday 8 October 2014

Binding ConverterParameter

There have been numerous cases where I've wanted to bind a ConverterParameter on a converter instance to either a property on another object or to a property on my view model.

XAML Binding
<Label Content="{Binding BoundedValue
            , Converter={StaticResource valueIfNullConverter}
            , ConverterParameter={Binding DefaultNullValue}}"/>
Converter
    public class ValueIfNullConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value ?? System.Convert.ToString(parameter);
        }
    }

Only to find this failing at runtime with the following exception:

A 'Binding' cannot be set on the 'ConverterParameter' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

This therefore implies the ConverterParameter property isn't exposed as a DependencyProperty and therefore can't be bound to.

To overcome this problem we can use a MultiBinding along with a multi-value converter whereby we bind the "values" of the converter to both the data source and converter parameter properties as follows:

        <Label>
            <Label.Content>
                <MultiBinding Converter="{StaticResource valueIfNullConverter}">
                    <Binding Path="BoundedValue" />
                    <Binding Path="DefaultNullValue" />
                </MultiBinding>
            </Label.Content>
        </Label>
And changing our converter to a multi-value converter:
    public class ValueIfNullConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (values != null && values.Length == 2)
            {
                return values[0] ?? System.Convert.ToString(values[1]);
            }

            return values;
        }
    }
In the multi-value converter above, the bound value and parameter are now accessible inside the 'values' collection argument instead of accessing the parameter through the 'parameter' argument.