Lazy initialization of a singleton
-
Following some links I arrived at this MSDN link[^] on exploring the singleton pattern. Now if you scroll to the example you see this code:
sealed class Singleton { private Singleton() {} public static readonly Singleton Instance = new Singleton(); }
There is a subtle bug in this implementation (besides that the constructor is private so the sealed keyword is not needed - but this is not a bug). Quote from the article:
"The Framework, during the JIT process, will initialize the static
property when (and only when) any method uses this static property.
If the property is not used, then the instance is not created.
More precisely, what happens during JIT is that the class gets constructed
and loaded when any static member of the class is used by any caller."However a simple test reveals that this is not quite true:
public class Singleton { public static readonly Singleton Instance = new Singleton(); private Singleton() { Console.WriteLine("Singleton constructor..."); } public void Test() { Console.WriteLine("Singleton.Test()"); } } public static void Main() { Console.WriteLine("In Main..."); Singleton.Instance.Test(); Console.WriteLine("Exiting Main..."); }
The correct way to do is to mark the constructor as static. More discussions on this page[^].
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
-
Following some links I arrived at this MSDN link[^] on exploring the singleton pattern. Now if you scroll to the example you see this code:
sealed class Singleton { private Singleton() {} public static readonly Singleton Instance = new Singleton(); }
There is a subtle bug in this implementation (besides that the constructor is private so the sealed keyword is not needed - but this is not a bug). Quote from the article:
"The Framework, during the JIT process, will initialize the static
property when (and only when) any method uses this static property.
If the property is not used, then the instance is not created.
More precisely, what happens during JIT is that the class gets constructed
and loaded when any static member of the class is used by any caller."However a simple test reveals that this is not quite true:
public class Singleton { public static readonly Singleton Instance = new Singleton(); private Singleton() { Console.WriteLine("Singleton constructor..."); } public void Test() { Console.WriteLine("Singleton.Test()"); } } public static void Main() { Console.WriteLine("In Main..."); Singleton.Instance.Test(); Console.WriteLine("Exiting Main..."); }
The correct way to do is to mark the constructor as static. More discussions on this page[^].
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
Subtle Bugs is a forum to post examples of interesting, aggravating and subtle bugs that you've found and fixed.
-
Subtle Bugs is a forum to post examples of interesting, aggravating and subtle bugs that you've found and fixed.
Well yes, that's what I did didn't I? I found this bug when trying out the example and I corrected it.
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
-
Following some links I arrived at this MSDN link[^] on exploring the singleton pattern. Now if you scroll to the example you see this code:
sealed class Singleton { private Singleton() {} public static readonly Singleton Instance = new Singleton(); }
There is a subtle bug in this implementation (besides that the constructor is private so the sealed keyword is not needed - but this is not a bug). Quote from the article:
"The Framework, during the JIT process, will initialize the static
property when (and only when) any method uses this static property.
If the property is not used, then the instance is not created.
More precisely, what happens during JIT is that the class gets constructed
and loaded when any static member of the class is used by any caller."However a simple test reveals that this is not quite true:
public class Singleton { public static readonly Singleton Instance = new Singleton(); private Singleton() { Console.WriteLine("Singleton constructor..."); } public void Test() { Console.WriteLine("Singleton.Test()"); } } public static void Main() { Console.WriteLine("In Main..."); Singleton.Instance.Test(); Console.WriteLine("Exiting Main..."); }
The correct way to do is to mark the constructor as static. More discussions on this page[^].
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
-
And 'sealed' means that the class cannot be inherted/destroys the 'virtuality' of a member variable/method, it has nothing to do with ctor accessibility.
Yes, but since the constructor is private and there is no public/protected constructor you can't derive from this class. I didn't say that using the sealed keyword is wrong just that in this case it is not needed.
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
-
Well yes, that's what I did didn't I? I found this bug when trying out the example and I corrected it.
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
No you didn't. And that's not how you presented it in your post anyway.
-
No you didn't. And that's not how you presented it in your post anyway.
I really don't understand why are you so offended by my post. It presents a bug and the solution, but if that offends anyone else I will delete my post. Thank you!
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
-
I really don't understand why are you so offended by my post. It presents a bug and the solution, but if that offends anyone else I will delete my post. Thank you!
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
don't delete your post, but what's probably bugging him is that this forum is about "I ran into this really weird and unexpected bug in my code... To fix it I had to....", not "Hahaha X messed up in the example they put in their documentation". The proper place to report problems with MS material is the MSDN feedback site. http://connect.microsoft.com/VisualStudio/feedback[^]
Otherwise [Microsoft is] toast in the long term no matter how much money they've got. They would be already if the Linux community didn't have it's head so firmly up it's own command line buffer that it looks like taking 15 years to find the desktop. -- Matthew Faithfull
-
don't delete your post, but what's probably bugging him is that this forum is about "I ran into this really weird and unexpected bug in my code... To fix it I had to....", not "Hahaha X messed up in the example they put in their documentation". The proper place to report problems with MS material is the MSDN feedback site. http://connect.microsoft.com/VisualStudio/feedback[^]
Otherwise [Microsoft is] toast in the long term no matter how much money they've got. They would be already if the Linux community didn't have it's head so firmly up it's own command line buffer that it looks like taking 15 years to find the desktop. -- Matthew Faithfull
Exactly. If you wrote a program based on this faulty information and it took a long time to finally realize that the problem was with the documentation and then went and found the correct way to write your program, then say that. But you certainly didn't fix the documentation. Plus, that article is more than five years and two (or more?) generations of the framework old, so take it with a grain of salt.
-
Following some links I arrived at this MSDN link[^] on exploring the singleton pattern. Now if you scroll to the example you see this code:
sealed class Singleton { private Singleton() {} public static readonly Singleton Instance = new Singleton(); }
There is a subtle bug in this implementation (besides that the constructor is private so the sealed keyword is not needed - but this is not a bug). Quote from the article:
"The Framework, during the JIT process, will initialize the static
property when (and only when) any method uses this static property.
If the property is not used, then the instance is not created.
More precisely, what happens during JIT is that the class gets constructed
and loaded when any static member of the class is used by any caller."However a simple test reveals that this is not quite true:
public class Singleton { public static readonly Singleton Instance = new Singleton(); private Singleton() { Console.WriteLine("Singleton constructor..."); } public void Test() { Console.WriteLine("Singleton.Test()"); } } public static void Main() { Console.WriteLine("In Main..."); Singleton.Instance.Test(); Console.WriteLine("Exiting Main..."); }
The correct way to do is to mark the constructor as static. More discussions on this page[^].
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
Hmm, so what is the bug? The method body refers to the member, hence when it (the method) gets loaded for execution/JIT'ing, the static constructor will run, and initialize all the fields.
xacc.ide - now with IronScheme support
IronScheme - 1.0 alpha 1 out now -
Following some links I arrived at this MSDN link[^] on exploring the singleton pattern. Now if you scroll to the example you see this code:
sealed class Singleton { private Singleton() {} public static readonly Singleton Instance = new Singleton(); }
There is a subtle bug in this implementation (besides that the constructor is private so the sealed keyword is not needed - but this is not a bug). Quote from the article:
"The Framework, during the JIT process, will initialize the static
property when (and only when) any method uses this static property.
If the property is not used, then the instance is not created.
More precisely, what happens during JIT is that the class gets constructed
and loaded when any static member of the class is used by any caller."However a simple test reveals that this is not quite true:
public class Singleton { public static readonly Singleton Instance = new Singleton(); private Singleton() { Console.WriteLine("Singleton constructor..."); } public void Test() { Console.WriteLine("Singleton.Test()"); } } public static void Main() { Console.WriteLine("In Main..."); Singleton.Instance.Test(); Console.WriteLine("Exiting Main..."); }
The correct way to do is to mark the constructor as static. More discussions on this page[^].
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
Correct lazy initialization of a Singleton requires thread synchronization and a real property and not a member. What you pointed out is not a bug in the framework but a bug in the article, I believe.
Need a C# Consultant? I'm available.
Happiness in intelligent people is the rarest thing I know. -- Ernest Hemingway -
Correct lazy initialization of a Singleton requires thread synchronization and a real property and not a member. What you pointed out is not a bug in the framework but a bug in the article, I believe.
Need a C# Consultant? I'm available.
Happiness in intelligent people is the rarest thing I know. -- Ernest HemingwayYes I pointed out a bug in the article, because it was an interesting and subtle bug that made me to read more on the subject.
Ennis Ray Lynch, Jr. wrote:
Correct lazy initialization of a Singleton requires thread synchronization and a real property and not a member.
The static constructor is guaranteed to be thread-safe by the framework. If I understand correctly the readonly keyword guards the Instance member so that assignment only occurs in the declaration (or in the constructor).
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
-
Yes I pointed out a bug in the article, because it was an interesting and subtle bug that made me to read more on the subject.
Ennis Ray Lynch, Jr. wrote:
Correct lazy initialization of a Singleton requires thread synchronization and a real property and not a member.
The static constructor is guaranteed to be thread-safe by the framework. If I understand correctly the readonly keyword guards the Instance member so that assignment only occurs in the declaration (or in the constructor).
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
Static constructor is not a valid Lazy Initialization. Any static method called on the singleton will result in the Singleton being initialized if the init is done in the static constructor. Best lazy loading occurs with the following pattern:
private static Foo mInstance = null;
public static Foo GetInstance(){
if(mInstance == null){
//Do some sort of thread locking to avoid double initizization
//As it stands, this code can create two instances of the singleton
mInstance = new Foo();
}
return mInstance;
}Need a C# Consultant? I'm available.
Happiness in intelligent people is the rarest thing I know. -- Ernest Hemingway -
Following some links I arrived at this MSDN link[^] on exploring the singleton pattern. Now if you scroll to the example you see this code:
sealed class Singleton { private Singleton() {} public static readonly Singleton Instance = new Singleton(); }
There is a subtle bug in this implementation (besides that the constructor is private so the sealed keyword is not needed - but this is not a bug). Quote from the article:
"The Framework, during the JIT process, will initialize the static
property when (and only when) any method uses this static property.
If the property is not used, then the instance is not created.
More precisely, what happens during JIT is that the class gets constructed
and loaded when any static member of the class is used by any caller."However a simple test reveals that this is not quite true:
public class Singleton { public static readonly Singleton Instance = new Singleton(); private Singleton() { Console.WriteLine("Singleton constructor..."); } public void Test() { Console.WriteLine("Singleton.Test()"); } } public static void Main() { Console.WriteLine("In Main..."); Singleton.Instance.Test(); Console.WriteLine("Exiting Main..."); }
The correct way to do is to mark the constructor as static. More discussions on this page[^].
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
A small point. The article is for .NET 1 or .NET 1.1. You couldn't have a static constructor then. These were introduced in .NET 2. The behaviour and optimisation of .NET has changed from the older versions so you can't really compare.
Deja View - the feeling that you've seen this post before.
-
A small point. The article is for .NET 1 or .NET 1.1. You couldn't have a static constructor then. These were introduced in .NET 2. The behaviour and optimisation of .NET has changed from the older versions so you can't really compare.
Deja View - the feeling that you've seen this post before.
Pete O'Hanlon wrote:
You couldn't have a static constructor then
You have static constructors in .NET 1.1, I'm not sure prior to .NET 1.1, so you may be right. I tried it in .NET 1.1.4322 in it works.
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
-
Pete O'Hanlon wrote:
You couldn't have a static constructor then
You have static constructors in .NET 1.1, I'm not sure prior to .NET 1.1, so you may be right. I tried it in .NET 1.1.4322 in it works.
Work @ Network integrated solutions | Flickr | A practical use of the MVC pattern
Damn my memory - I was sure this was the case. It's been so long since I've used .NET 1 that some things are hazy, but I was pretty damned sure of this. Oh well.
Deja View - the feeling that you've seen this post before.