Ejemplo n.º 1
0
        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());
    }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
        /// <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);
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        /// <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);
        }
Ejemplo n.º 8
0
        /// <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);
    }