Exemplo n.º 1
0
        private T FullMode(Func <T> valueFactory, ManualResetEvent waitHandle, ref Thread thread, ref int preIsValueCreated)
        {
back:
            if (Interlocked.CompareExchange(ref preIsValueCreated, 1, 0) == 0)
            {
                try
                {
                    thread = Thread.CurrentThread;
                    GC.KeepAlive(thread);
                    _target       = valueFactory.Invoke();
                    _valueFactory = FuncHelper.GetReturnFunc(_target);
                    Thread.VolatileWrite(ref _isValueCreated, 1);
                    return(_target);
                }
                catch (Exception)
                {
                    Thread.VolatileWrite(ref preIsValueCreated, 0);
                    throw;
                }
                finally
                {
                    waitHandle.Set();
                    thread = null;
                }
            }
            else
            {
                if (ReferenceEquals(thread, Thread.CurrentThread))
                {
                    throw new InvalidOperationException();
                }
                else
                {
                    waitHandle.WaitOne();
                    if (Thread.VolatileRead(ref _isValueCreated) == 1)
                    {
                        return(_valueFactory.Invoke());
                    }
                    else
                    {
                        goto back;
                    }
                }
            }
        }
Exemplo n.º 2
0
        private T NoneMode(Func <T> valueFactory, HashSet <Thread> threads)
        {
            // NOTICE this method has no null check
            var currentThread = Thread.CurrentThread;

            if (Thread.VolatileRead(ref _isValueCreated) == 0)
            {
                try
                {
                    // lock (threads) // This is meant to not be thread-safe
                    {
                        if (threads.Contains(currentThread))
                        {
                            throw new InvalidOperationException();
                        }
                        else
                        {
                            threads.Add(currentThread);
                        }
                    }
                    _target       = valueFactory();
                    _valueFactory = FuncHelper.GetReturnFunc(_target);
                    Thread.VolatileWrite(ref _isValueCreated, 1);
                    return(_target);
                }
                catch (Exception)
                {
                    Thread.VolatileWrite(ref _isValueCreated, 0);
                    throw;
                }
                finally
                {
                    // lock (threads) // This is meant to not be thread-safe
                    {
                        threads.Remove(Thread.CurrentThread);
                    }
                }
            }
            else
            {
                return(_valueFactory.Invoke());
            }
        }