All pastes #720934 Raw Edit

Miscellany

public text v1 · immutable
#720934 ·published 2007-09-30 20:22 UTC
rendered paste body
/// <summary>
    /// Syncronized List{T} based on SynchronizedDictionary provided by Nomad
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SyncronizedList<T> : List<T>
    {
        private readonly ReaderWriterLockSlim m_rwLock = new ReaderWriterLockSlim();
        private volatile int m_userLock = 0;

        public SyncronizedList() : base() { }
        public SyncronizedList(int capacity) : base(capacity){}
        public SyncronizedList(IEnumerable<T> collection) : base(collection) { }

        public new T this[int index]
        {
            get
            {
                if (m_rwLock != 0 && m_userLock == Thread.CurrentThread.ManagedThreadId)
                {
                    return base[index];
                }

                T result;
                try
                {
                    m_rwLock.EnterReadLock();
                    // redundant, same code called in base[index]
                    /*
                    if (index > Count)
                    {
                        //m_rwLock.ExitReadLock();
                        throw new ArgumentOutOfRangeException("index");
                    }*/

                    result = base[index];
                }
                finally
                {
                    m_rwLock.ExitReadLock();
                }

                return result;
            }
            set
            {
                if (m_userLock != 0 && m_userLock == Thread.CurrentThread.ManagedThreadId)
                {
                    base[key] = value;
                    return;
                }

                bool upgraded = true;
                m_rwLock.EnterUpgradeableReadLock();
                try
                {
                    if (index > Count)
                    {
                        m_rwLock.EnterWriteLock();
                        try
                        {
                            base.Add(value);
                        }
                        finally
                        {
                            m_rwLock.ExitWriteLock();
                        }
                    }
                    else
                    {
                        m_rwLock.EnterReadLock();
                        m_rwLock.ExitUpgradeableReadLock();
                        upgraded = false;
                        try
                        {
                            base[index] = value;
                        }
                        finally
                        {
                            m_rwLock.ExitReadLock();
                        }
                    }
                }
                finally
                {
                    if (upgraded)
                        m_rwLock.ExitUpgradeableReadLock();
                }
            }
        }
    }