Click here to Skip to main content
15,887,135 members
Articles / Mobile Apps / Windows Mobile

SingleInstance(Of T) Class for Windows Phone 7

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
14 May 2011CPOL2 min read 13.6K   4   1
This post aims to provide a way to implement lazy initialization in a multi threaded environment using the SingleInstance(Of T) Class.

When building applications for a mobile operating system such as Windows Phone 7 (WP7), you might want (at times) to defer the creation of large objects, specifically when this creation is going to increase memory consumption. While in the desktop CLR there is the Lazy(Of T) Class, when working on WP7, this class does not exist (at least not at the time of this writing).

I find it a very repetitive task to manually produce a single instance object:

  1. Make its constructor private.
  2. Write the code for initialization.
  3. Provide a getter method that returns the one and only instance.

While you cannot avoid step 2, it is possible to create a generic class that produces step 1 and step 3. Then, from the class constructor, you can pass the code that creates the object using a Func(TResult) Delegate.

Update: The first version of the SingleInstance(Of T) class provided an option to create an instance (Of T) using the thread pool. This option is removed in the current version.

SingleInstance(Of T) Class

C#
using System;
using System.Threading;

public sealed class SingleInstance<T> where T : class
{
    private readonly Object m_lockObj = new Object();
    private readonly Func<T> m_delegate;
    private Boolean m_isDelegateInvoked;

    private T m_value;

    /// <summary>
    /// Initializes a new instance of the
    /// <see cref="SingleInstance&lt;T&gt;"/> class.
    /// </summary>
    public SingleInstance()
        : this(() => default(T)) { }

    /// <summary>
    /// Initializes a new instance of the
    /// <see cref="SingleInstance&lt;T&gt;"/> class.
    /// </summary>
    /// <param name="delegate">The @delegate.</param>
    public SingleInstance(Func<T> @delegate)
    {
        m_delegate = @delegate;
    }

    /// <summary>
    /// Gets the instance.
    /// </summary>
    /// <value>The instance.</value>
    public T Instance
    {
        get
        {
            if (!m_isDelegateInvoked)
            {
                T temp = m_delegate();
                Interlocked.CompareExchange<T>(ref m_value, temp, null);

                Boolean lockTaken = false;

                try
                {
                    // WP7 does not support the overload with the
                    // Boolean indicating if the lock was taken.
                    Monitor.Enter(m_lockObj); lockTaken = true;

                    m_isDelegateInvoked = true;
                }
                finally
                {
                    if (lockTaken) { Monitor.Exit(m_lockObj); }
                }
            }

            return m_value;
        }
    }
}

The SingleInstance(Of T) class has many differences from the System.Lazy(Of T) class in the desktop CLR.

  • The System.Lazy(Of T) class takes a LazyThreadSafetyMode enumeration. This enumeration contains 3 members (None, PublicationOnly, ExecutionAndPublication). The SingleInstance(Of T) class uses the interlocked constructs to produce a single instance. This is similar with passing LazyThreadSafetyMode.ExecutionAndPublication in the System.Lazy(Of T) class.
  • The System.Lazy(Of T) class works with classes (reference types) and structs (value types). The value types are boxed internally. The SingleInstance(Of T) class works only with reference types.
  • Finally, the System.Lazy(Of T) class is written, tested and supported by Microsoft, while the SingleInstance(Of T) is not.

Keep in mind that the SingleInstance(Of T) class uses a Func(TResult) delegate. There is a known performance hit when calling delegates compared to direct method calls. (See the Delegates section here.)

This article was originally posted at http://www.nikosbaxevanis.com/bonus-bits

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
QuestionWhy the differences? Pin
hfrmobile12-May-12 11:04
hfrmobile12-May-12 11:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.