现在我有一个这样的需求,在一个集合中。同时有多个现成访问集合的元素,在访问的同时,还可能会对集合进行排序。而这种情况下,可能在遇到正在排序的过程中枚举成员,造成存在的集合元素没有被找出来。请问,这样的情况有没有解决方案?

解决方案 »

  1.   

    加锁啊,特别对于排序时,只允许一个线程访问,排序完后,解锁,其他线程才可进入,最简单的 lock 
      

  2.   

    因为我的排序是异步进行的。所以排序也有可能是多个线程。  现在造成的情况是,在排序之前获取了枚举器,然后排序,然后枚举这样就会找不到元素了。我贴下我的代码吧,希望高手能够给与指点。在下感谢了:    public class XmlConfigSortedList<T> : List<T>, IEnumerable<T>
            where T : IMatchedContainer
        {
            /// <summary>
            /// 获取当前集合中项的总被匹配次数。
            /// </summary>
            public long MatchCount { get; private set; }        /// <summary>
            /// 当集合中存在一个匹配的配置节点。则事件会被触发
            /// </summary>
            protected event MatchCompletedDelegate<T> MatchCompleted;        /// <summary>
            /// 构造方法
            /// </summary>
            public XmlConfigSortedList()
            {
                this.MatchCompleted += CurrentItemStatusChanged;
                this.MatchCompleted += Sort;
            }        void Sort(object sender, T e)
            {
                const int n = 5;
                //每N次匹配成功,就进行一次排序。
                //if (this.MatchCount % n == 0)
                {
                    
                    //QueueWorkForSort(this);
                    AsynchronizeSort(this);
                }
            }        void CurrentItemStatusChanged(object sender, T e)
            {
                e.MatchSuccess();
                this.MatchCount++;
            }        /// <summary>
            /// 指示当前集合成功匹配了指定项。并同时维护集合状态。也同时指示当前集合针对参数T成功匹配过一次。该方法一定会抛出
            /// </summary>
            /// <param name="matchItem">已被匹配的对象</param>
            public void MatchedFor(T matchItem)
            {
                MatchCompleted(this, matchItem);
            }        public new IEnumerator<T> GetEnumerator()
            {
                lock (this)
                {
                    //var arr = new T[this.Count];
                    //CopyTo(arr);
                    //return arr.AsEnumerable().GetEnumerator();
                    return base.GetEnumerator();
                }
            }        /// <summary>
            /// 异步对指定对象进行排序。
            /// </summary>
            /// <param name="lst">要进行排序的对象</param>
            private void AsynchronizeSort(XmlConfigSortedList<T> lst)
            {
                int availableThreads;
                int completedThreads;
                ThreadPool.GetAvailableThreads(out availableThreads, out completedThreads);            if (availableThreads > 0)
                {
                    ThreadPool.QueueUserWorkItem(QueueWorkForSort, lst);
                }
            }        private void QueueWorkForSort(object data)
            {
                lock (this)
                {
                    XmlConfigSortedList<T> list = data as XmlConfigSortedList<T>;
                    if (list != null)
                    {
                        list.Sort(new Comparison<T>((i1, i2) => i2.MatchCount.CompareTo(i1.MatchCount)));                }
                }        }
        }    /// <summary>
        /// 指示指定的集合对象已完成排序。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void MatchCompletedDelegate<in T>(object sender, T e) where T : IMatchedContainer;