zoukankan      html  css  js  c++  java
  • 线程安全的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)
            {
                
    lock (sessions)
                {
                    
    if (sessions.ContainsKey(sessionID))
                    {
                        db.Delete(GetSessionFromDatabase(sessionID));
                        dispatcher.UnregisterAllOutEventSubscriber(sessionID);
                        sessions.Remove(sessionID);
                    }
                }
            }


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

           private void CheckingTimeout()
            {
                List
    <string> list = new List<string>();
                
    lock (sessions)
                {
                    
    foreach (string sessionKey in sessions.Keys)
                    {
                        
    if (sessions[sessionKey].IsTimeouted)
                        {
                            logger.Info(
    "会话 [" + sessionKey + "] 超时");
                            UnregisterSession(sessionKey);
                            list.Add(sessionKey);
                        }
                    }
                    
    foreach (string key in list)
                    {
                        sessions.Remove(key);              
                    }
                }
            }

            
    private void UnregisterSession(string sessionID)
            {
                
    lock (sessions)
                {
                    
    if (sessions.ContainsKey(sessionID))
                    {
                        db.Delete(GetSessionFromDatabase(sessionID));
                        dispatcher.UnregisterAllOutEventSubscriber(sessionID);
                    }
                }
            }

     

    欢迎大家扫描下面二维码成为我的客户,为你服务和上云

  • 相关阅读:
    PHP 错误:Warning: Cannot modify header information
    PHP截取中文字符串
    myeclipse 保存含中文的jsp失败,提示内容含有 ISO-8859-1 不支持的字符
    jquery ajax到servlet出现中文乱码(utf-8编码下)
    数据结构~动态存储管理(五)
    数据结构~树和二叉树(三)
    数据结构~线性表(二)
    数据结构~基础概念(一)
    每日一摘:串并-并串转换
    每日一摘:Verilog复位
  • 原文地址:https://www.cnblogs.com/shanyou/p/386012.html
Copyright © 2011-2022 走看看