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.