C # Singleton Thread Safety

I am reading Jon Skeet's definitive post on how to implement C # singleton and I am following below pattern. Note that I do not have an empty ctor. My Ctor can do some work like create and populate an array of strings (or create some objects and assign them to private variables, etc.):

public class MyClass
    {                
        /// <summary>
        /// Get singleton instance of this class.
        /// </summary>
        public static readonly MyClass Instance = new MyClass();


        /// <summary>
        /// a collection of strings.
        /// </summary>
        private string[] strings;        

        private MyClass()
        {            
            this.strings = new string[]
            {
                "a",
                "b",
                "c",
                "d",
                "e" 
            };
        }

        public void MyMethod()
        {
           // tries to use this.strings.
           // can a null ref exception happen here when running multithreaded code?
        }
}

      

above thread safety? I ask because I have similar code running on an asp.net app server and getting a null ref exception in the logs (not sure if the null reference refers to above), I think not, and the call stack in the log is not helps).

+3


source to share


2 answers


I honestly don't see a reason why this shouldn't be thread safe. Especially considering that the fourth quarter version in the fourth quarter is essentially the same.

The only problem I see is that you don't have a static constructor. (this can cause problems, see this ). If you add a static constructor (even if it's empty), you end up with what Jon Skeet calls thread safe.



public class MyClass
{
    public static readonly MyClass Instance = new MyClass();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static MyClass() { }
}

      

+1


source


According to the referenced article by Jon Skeet, adding a static constructor will result in this implementation being thread safe:

Laziness of type initializers is only guaranteed by .NET when the type is not marked with a special flag called beforefieldinit. Unfortunately, the C # compiler (as provided in the .NET 1.1 runtime) marks all types that don't have a static constructor (i.e. a block that looks like a constructor but is marked static) as beforefieldinit

(see http://csharpindepth.com/articles/general/singleton.aspx#cctor )



The way you do it now, it is not thread safe. If you do something like this, it becomes thread safe:

public class MyClass
{
    /// <summary>
    /// Get singleton instance of this class
    /// </summary>
    public static readonly MyClass Instance = new MyClass();

    static MyClass()
    {
        //causes the compiler to not mark this as beforefieldinit, giving this thread safety
        //for accessing the singleton.
    }

    //.. the rest of your stuff..
}

      

+1


source







All Articles