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).
source to share
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() { }
}
source to share
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..
}
source to share