天天看点

线程安全的Generic Dictionary

 System.Collections.Generic.Dictionary<,>

只要不修改该集合,

Dictionary

就可以同时支持多个阅读器。即便如此,从头到尾对一个集合进行枚举本质上并不是一个线程安全的过程。当出现枚举与写访问互相争用这种极少发生的情况时,必须在整个枚举过程中锁定集合。若要允许多个线程访问集合以进行读写操作,则必须实现自己的同步。今天解决了使用Dictionary泛型类的时候出现一个错误 “System.InvalidOpervationException "集合已经修改,可能无法执行枚举操作"”。原来的代码如下:

        private void CheckingTimeout() 

        {

            List<string> list = new List<string>();

            lock (sessions)

            {

                foreach (string sessionKey in sessions.Keys)

                {

                    if (sessions[sessionKey].IsTimeouted) 

                    {

                        logger.Info("会话 [" + sessionKey + "] 超时");

                        UnLoadSession(sessionKey);

                        list.Add(sessionKey);

                    }

                }

                foreach (string key in list)

                    sessions.Remove(key);              

            }

        } 

      public void UnloadSession(string sessionID)

                if (sessions.ContainsKey(sessionID))

                    db.Delete(GetSessionFromDatabase(sessionID));

                    dispatcher.UnregisterAllOutEventSubscriber(sessionID);

                    sessions.Remove(sessionID);

        }

错误出现的原因是代码中在枚举的过程中修改了集合,而造成了这个错误,修改后的代码如下:

       private void CheckingTimeout()

                    if (sessions[sessionKey].IsTimeouted)

                        UnregisterSession(sessionKey);

        private void UnregisterSession(string sessionID)

自由、创新、研究、探索……

继续阅读