线程安全的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);
                }
            }
        }

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值