/// <summary> /// local helper method to initialize the value /// </summary> /// <returns>The inititialized T value</returns> private T LazyInitValue() { Boxed boxed = null; LazyThreadSafetyMode mode = Mode; if (mode == LazyThreadSafetyMode.None) { boxed = CreateValue(); m_boxed = boxed; } else if (mode == LazyThreadSafetyMode.PublicationOnly) { boxed = CreateValue(); if (boxed == null || Interlocked.CompareExchange(ref m_boxed, boxed, null) != null) { // If CreateValue returns null, it means another thread successfully invoked the value factory // and stored the result, so we should just take what was stored. If CreateValue returns non-null // but we lose the ---- to store the single value, again we should just take what was stored. boxed = (Boxed)m_boxed; } else { // We successfully created and stored the value. At this point, the value factory delegate is // no longer needed, and we don't want to hold onto its resources. m_valueFactory = ALREADY_INVOKED_SENTINEL; } } else { object threadSafeObj = Volatile.Read(ref m_threadSafeObj); try { if (threadSafeObj != (object)ALREADY_INVOKED_SENTINEL) { Monitor.Enter(threadSafeObj); } else { Guard.Assert(m_boxed != null, new ArgumentException()); } if (m_boxed == null) { boxed = CreateValue(); m_boxed = boxed; Volatile.Write(ref m_threadSafeObj, ALREADY_INVOKED_SENTINEL); } else // got the lock but the value is not null anymore, check if it is created by another thread or faulted and throw if so { Guard.Assert(boxed != null, new ArgumentException()); } } finally { Monitor.Exit(threadSafeObj); } } Guard.Assert(boxed != null, new ArgumentException()); return(boxed.m_value); }