天天看點

線程安全的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)

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

繼續閱讀