private T LazyInitValue() { Boxed boxed; switch (Mode) { case LazyThreadSafetyMode.None: boxed = CreateValue(); m_Boxed = boxed; break; case LazyThreadSafetyMode.PublicationOnly: boxed = CreateValue(); object mBoxed = m_Boxed; if (Interlocked.CompareExchange(ref mBoxed, boxed, null) != null) { boxed = (Boxed)m_Boxed; } break; default: { object obj2; bool lockTaken = Monitor.TryEnter(obj2 = m_ThreadSafeObj); try { if (m_Boxed == null) { boxed = CreateValue(); m_Boxed = boxed; } else { boxed = m_Boxed as Boxed; if (boxed == null) { LazyInternalExceptionHolder holder = (LazyInternalExceptionHolder)m_Boxed; throw holder.Exception; } } } finally { if (lockTaken) { Monitor.Exit(obj2); } } break; } } return(boxed.Value); }
public async Task <T> FetchValueAsync() { Boxed boxed = null; if (this.boxed != null) { // Do a quick check up front for the fast path. boxed = this.boxed as Boxed; if (boxed != null) { return(boxed.value); } LazyInternalExceptionHolder exc = this.boxed as LazyInternalExceptionHolder; exc.m_edi.Throw(); } return(await LazyInitValue()); }
private bool TryGetValueOrThrowException(out T value) { Boxed boxed = m_value as Boxed; if (boxed != null) { value = boxed.Value; return(true); } LazyInternalExceptionHolder exHolder = m_value as LazyInternalExceptionHolder; exHolder?.ExceptionInfo.Throw(); value = default(T); return(false); }
/// <summary> /// local helper method to initialize the value /// </summary> /// <returns>The inititialized T value</returns> private TResult LazyInitValue() { Boxed boxed = null; object threadSafeObj = Volatile.Read(ref m_threadSafeObj); bool lockTaken = false; try { if (threadSafeObj != (object)ALREADY_INVOKED_SENTINEL) { Monitor.Enter(threadSafeObj, ref lockTaken); } else { Contract.Assert(m_boxed != null); } 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 { boxed = m_boxed as Boxed; if (boxed == null) // it is not Boxed, so it is a LazyInternalExceptionHolder { LazyInternalExceptionHolder exHolder = m_boxed as LazyInternalExceptionHolder; Contract.Assert(exHolder != null); exHolder.m_edi.Throw(); } } } finally { if (lockTaken) { Monitor.Exit(threadSafeObj); } } Contract.Assert(boxed != null); return(boxed.m_value); }
/// <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 (Interlocked.CompareExchange(ref m_boxed, boxed, null) != null) { boxed = (Boxed)m_boxed; // set the boxed value to the succeeded thread value } } else { lock (m_threadSafeObj) { if (m_boxed == null) { boxed = CreateValue(); m_boxed = boxed; } 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 { boxed = m_boxed as Boxed; if (boxed == null) // it is not Boxed, so it is a LazyInternalExceptionHolder { LazyInternalExceptionHolder exHolder = m_boxed as LazyInternalExceptionHolder; Contract.Assert(exHolder != null); throw exHolder.m_exception; } } } } Contract.Assert(boxed != null); return(boxed.m_value); }
private T LazyInitValue() { Boxed <T> boxed = null; switch (this.Mode) { case LazyThreadSafetyMode.None: boxed = this.CreateValue(); this.m_boxed = boxed; break; case LazyThreadSafetyMode.PublicationOnly: boxed = this.CreateValue(); if (Interlocked.CompareExchange(ref this.m_boxed, boxed, null) != null) { boxed = (Boxed <T>) this.m_boxed; } break; default: lock (this.m_threadSafeObj) { if (this.m_boxed == null) { boxed = this.CreateValue(); this.m_boxed = boxed; } else { boxed = this.m_boxed as Boxed <T>; if (boxed == null) { LazyInternalExceptionHolder <T> holder = this.m_boxed as LazyInternalExceptionHolder <T>; throw holder.m_exception; } } } break; } return(boxed.m_value); }
/// <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 (m_boxed == null) { boxed = CreateValue(); m_boxed = boxed; } 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 { boxed = m_boxed as Boxed; if (boxed == null) // it is not Boxed, so it is a LazyInternalExceptionHolder { LazyInternalExceptionHolder exHolder = m_boxed as LazyInternalExceptionHolder; System.Diagnostics.Debug.Assert(exHolder != null); throw exHolder.m_exception; } } System.Diagnostics.Debug.Assert(boxed != null); return(boxed.m_value); }
/// <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 another thread set the value 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 = m_threadSafeObj; bool lockTaken = false; try { if (threadSafeObj != (object)ALREADY_INVOKED_SENTINEL) { Monitor2.Enter(threadSafeObj, ref lockTaken); } else { Debug.Assert(m_boxed != null); } if (m_boxed == null) { boxed = CreateValue(); m_boxed = boxed; 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 { boxed = m_boxed as Boxed; if (boxed == null) // it is not Boxed, so it is a LazyInternalExceptionHolder { LazyInternalExceptionHolder exHolder = m_boxed as LazyInternalExceptionHolder; Debug.Assert(exHolder != null); exHolder.m_edi.Throw(); } } } finally { if (lockTaken) { Monitor.Exit(threadSafeObj); } } } Debug.Assert(boxed != null); return(boxed.m_value); }
/// <summary> /// local helper method to initialize the value /// </summary> /// <returns>The inititialized T value</returns> private async Task <T> LazyInitValue() { Boxed boxed = null; LazyThreadSafetyMode mode = Mode; if (mode == LazyThreadSafetyMode.None) { boxed = await CreateValue(); this.boxed = boxed; } else if (mode == LazyThreadSafetyMode.PublicationOnly) { boxed = await CreateValue(); if (boxed == null || Interlocked.CompareExchange(ref this.boxed, boxed, null) != null) { boxed = (Boxed)this.boxed; } else { valueFactory = alreadyInvokedSentinel; } } else { object threadSafeObject = Volatile.Read(ref threadSafeObj); bool lockTaken = false; try { if (threadSafeObject != (object)alreadyInvokedSentinel) { Monitor.Enter(threadSafeObject, ref lockTaken); } else { Contract.Assert(this.boxed != null); } if (this.boxed == null) { boxed = await CreateValue(); this.boxed = boxed; Volatile.Write(ref threadSafeObj, alreadyInvokedSentinel); } else { boxed = this.boxed as Boxed; if (boxed == null) // it is not Boxed, so it is a LazyInternalExceptionHolder { LazyInternalExceptionHolder exHolder = this.boxed as LazyInternalExceptionHolder; Contract.Assert(exHolder != null); exHolder.m_edi.Throw(); } } } finally { if (lockTaken) { Monitor.Exit(threadSafeObject); } } } Contract.Assert(boxed != null); return(boxed.value); }