Hi Ingo, You should probably check Mark Townsends (MS) article in MSDN "Exploring the Singleton Design Pattern" where he particularly mention use of the static constructors for this matter.
-Valery. PS. Thanks for kind words;) -----Original Message----- From: Ingo Lundberg [mailto:[EMAIL PROTECTED]] Sent: Tuesday, April 30, 2002 11:52 AM To: [EMAIL PROTECTED] Subject: Re: [DOTNET] lock - how expensive is it to call? Valery, Thanks for pitching in. I'll take you word for it. I have the highest regards for your knowledge. How come, do you think, one never sees samples with singletons using the static constructor? Is my MySingle2 equivalent to MySingleton? I would guess that the field initialization of MySingle2.theInstance is actually executed the same time that the static constructor is executed. Is this protected by the framework too? /Ingo On Tue, 30 Apr 2002 11:35:42 +0200, Valery Pryamikov <[EMAIL PROTECTED]> wrote: >Yes, it's safe to initialize singleton from the static constructor, >which is properly protected by framework. Check list archives for more >details and/or 9.5.3 of PartitionIIMetadata.doc. > >In short: static constructors are always properly protected, but there >is a possibility of seeing partially initialized and zeroed out static >data of the object but only from the static constructor of other type in >case if there is a cyclic dependency like: >class A:{public static B b;}; >class B:{public static A a;}; > >or any other variation. > >Note that there will be no deadlocks/exceptions in .Net in case of such >cyclic dependency even in MT scenarios. > >-Valery. > >-----Original Message----- >From: Ingo Lundberg [mailto:[EMAIL PROTECTED]] >Sent: Tuesday, April 30, 2002 11:02 AM >To: [EMAIL PROTECTED] >Subject: Re: [DOTNET] lock - how expensive is it to call? > >Hi there, > >I hope it isn't too late to jump in and ask a few questions. >I don't now if this thread was about creating singletons to begin with >but >my question is about just that. Vance Morrison's posting was about >singletons anyway. > >How about creating the singleton instance in the static constructor? >Is that bad? >What's the semantics of the static constructor? >Is it guaranteed to run only once? >Thread safe? >What about static members initiated where they are declared? >Only once? >Thread safe? >What's wrong with these two classes from a threading perspective. > >TIA >/Ingemar > > public class MySingleton > { > static MySingleton theInstance; > private MySingleton() {} > static MySingleton() > { > theInstance = new MySingleton(); > } > public MySingleton Instance{ get{return theInstance;} } > } > > public class MySingle2 > { > static MySingle2 theInstance = new MySingle2(); > private MySingle2() {} > public MySingle2 Instance{ get{return theInstance;} } > } > > > >On Mon, 29 Apr 2002 14:29:46 +0200, Valery Pryamikov ><[EMAIL PROTECTED]> wrote: > >>Your latest code should work, of course, but using second lock would be >>quite an expensive addition... And you only need a memory write barrier >>between <init stuff> and bNeedInit = false. Using two different >>fNeedInit+fNeedInitInt fields is more efficient solution for lazy init >>problem (you already have mem.barrier during lock release). >> >>Cheers, >>-Valery. >> >>-----Original Message----- >>From: Henk de Koning [mailto:[EMAIL PROTECTED]] >>Sent: Monday, April 29, 2002 2:18 PM >>To: [EMAIL PROTECTED] >>Subject: Re: [DOTNET] lock - how expensive is it to call? >> >>Hmm, I had been thinking of >> >>if (bNeedInit) >>{ >> lock(this) >> { >> if (bNeedInit) >> { >> lock(this) >> { >> <init stuff> >> } >> bNeedInit = false; >> } >> } >>} >> >>I agree with you that there was still a problem in the code I posted >>(although you must admit that it would safely initialize the value of >>variable bNeedInit ;-). About threads, sure they can hop across cpu's. >>However, the point was of course that while a thread is scheduled, it >>will >>run on one cpu only. Context switches surely don't alter the code >>sequence >>being executed ;-). I agree with you on your point that memory access >>from >>one cpu to one mem location is not reordered. That's the rule I was >>referring to. >> >>So, what can we learn from this: never post code from the top of your >>head >>and then respond to emails without rereading what you posted ;-);-). >> >>-- Henkk >> >>----- Original Message ----- >>From: "Valery Pryamikov" <[EMAIL PROTECTED]> >>To: <[EMAIL PROTECTED]> >>Sent: Monday, April 29, 2002 1:34 PM >>Subject: Re: [DOTNET] lock - how expensive is it to call? >> >> >>> BTW: >>> This kind of lazy init problem could be corrected following way: >>> >>> if (fNeedInit) { >>> lock (this) { >>> if (fNeedInitInt) { >>> <init stuff> >>> fNeedInitInt = false; >>> } >>> } //write barrier is performed by lock's release. >>> fNeedInit = false; >>> } >>> >>> Note: second if checks internal fNeedInitInt variable and fNeedInit >is >>> updated outside of lock region. >>> (of course we consider that bNeedInit/fNeedInit/fNeedInitInt are not >>> volatile). >>> >>> -Valery. >>> >> >>You can read messages from the DOTNET archive, unsubscribe from DOTNET, >or >>subscribe to other DevelopMentor lists at http://discuss.develop.com. > >You can read messages from the DOTNET archive, unsubscribe from DOTNET, >or >subscribe to other DevelopMentor lists at http://discuss.develop.com. > >You can read messages from the DOTNET archive, unsubscribe from DOTNET, or >subscribe to other DevelopMentor lists at http://discuss.develop.com. You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com. You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.