Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. Clever Code
  4. Lazy initialization of a singleton

Lazy initialization of a singleton

Scheduled Pinned Locked Moved Clever Code
csharphtmlasp-netcomsysadmin
16 Posts 7 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Offline
    Z Offline
    Zoltan Balazs
    wrote on last edited by
    #1

    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

    P O L E P 5 Replies Last reply
    0
    • Z Zoltan Balazs

      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

      P Offline
      P Offline
      PIEBALDconsult
      wrote on last edited by
      #2

      Subtle Bugs is a forum to post examples of interesting, aggravating and subtle bugs that you've found and fixed.

      Z 1 Reply Last reply
      0
      • P PIEBALDconsult

        Subtle Bugs is a forum to post examples of interesting, aggravating and subtle bugs that you've found and fixed.

        Z Offline
        Z Offline
        Zoltan Balazs
        wrote on last edited by
        #3

        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

        P 1 Reply Last reply
        0
        • Z Zoltan Balazs

          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

          O Offline
          O Offline
          OR0N
          wrote on last edited by
          #4

          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.

          Z 1 Reply Last reply
          0
          • O OR0N

            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.

            Z Offline
            Z Offline
            Zoltan Balazs
            wrote on last edited by
            #5

            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

            1 Reply Last reply
            0
            • Z Zoltan Balazs

              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

              P Offline
              P Offline
              PIEBALDconsult
              wrote on last edited by
              #6

              No you didn't. And that's not how you presented it in your post anyway.

              Z 1 Reply Last reply
              0
              • P PIEBALDconsult

                No you didn't. And that's not how you presented it in your post anyway.

                Z Offline
                Z Offline
                Zoltan Balazs
                wrote on last edited by
                #7

                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

                D 1 Reply Last reply
                0
                • Z Zoltan Balazs

                  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

                  D Offline
                  D Offline
                  Dan Neely
                  wrote on last edited by
                  #8

                  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

                  P 1 Reply Last reply
                  0
                  • D Dan Neely

                    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

                    P Offline
                    P Offline
                    PIEBALDconsult
                    wrote on last edited by
                    #9

                    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.

                    1 Reply Last reply
                    0
                    • Z Zoltan Balazs

                      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

                      L Offline
                      L Offline
                      leppie
                      wrote on last edited by
                      #10

                      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

                      1 Reply Last reply
                      0
                      • Z Zoltan Balazs

                        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

                        E Offline
                        E Offline
                        Ennis Ray Lynch Jr
                        wrote on last edited by
                        #11

                        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

                        Z 1 Reply Last reply
                        0
                        • E Ennis Ray Lynch Jr

                          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

                          Z Offline
                          Z Offline
                          Zoltan Balazs
                          wrote on last edited by
                          #12

                          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

                          E 1 Reply Last reply
                          0
                          • Z Zoltan Balazs

                            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

                            E Offline
                            E Offline
                            Ennis Ray Lynch Jr
                            wrote on last edited by
                            #13

                            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

                            1 Reply Last reply
                            0
                            • Z Zoltan Balazs

                              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

                              P Offline
                              P Offline
                              Pete OHanlon
                              wrote on last edited by
                              #14

                              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.

                              My blog | My articles

                              Z 1 Reply Last reply
                              0
                              • P Pete OHanlon

                                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.

                                My blog | My articles

                                Z Offline
                                Z Offline
                                Zoltan Balazs
                                wrote on last edited by
                                #15

                                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

                                P 1 Reply Last reply
                                0
                                • Z Zoltan Balazs

                                  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

                                  P Offline
                                  P Offline
                                  Pete OHanlon
                                  wrote on last edited by
                                  #16

                                  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.

                                  My blog | My articles

                                  1 Reply Last reply
                                  0
                                  Reply
                                  • Reply as topic
                                  Log in to reply
                                  • Oldest to Newest
                                  • Newest to Oldest
                                  • Most Votes


                                  • Login

                                  • Don't have an account? Register

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • World
                                  • Users
                                  • Groups