有一个网站(成长家园www.aoecn.cn)项目中,使用了Hashtable来维护在线用户的状态,具体代码如下:

代码
Hashtable hs = getCacheHs();//从全局缓存中取出 Hashtable 表
if(hs.Contains(uid)){ //比较Hashtable 表中是否有这个用户
  hs[uid] = DateTime.Now;//有用户的更新最后活动时间
}else{
  hs.Add(uid, DateTime.Now);
//没有的插入一个新的行
}

 DateTime t1 
= getUpdateTime();//取得保存的上次更新时间
            DateTime nowt = DateTime.Now;

            TimeSpan ts 
= nowt - t1;
            
if (ts.Minutes >2)
            {
                
//大于2分钟就把Hashtable表中的数据更新到数据库中
                lock (hs)
                {
                    
foreach (DictionaryEntry o in hs)
                    {
                        Updata(o.Key, o.Value);
//更新到数据库方法
                    }
                    hs.Clear();
//清空Hashtable
                    setUpdateTime(DateTime.Now);//保存这次更新时间
                }

            }
        SaveCacheHs(hs);//保存到全局缓存里

 

 


现在问题出来了,如果正在执行foreach 的时候,又有另一个请求来执行hs.Add(uid, DateTime.Now);那么程序会报错说“Hashtable表中的集合已修改;可能无法执行枚举操作。”

所以要把lock锁住整个操作方法,修改后代码如下:

代码
Hashtable hs = getCacheHs();//从全局缓存中取出 Hashtable 表

lock (hs) //要锁住操作Hashtable 的整个过程
{
if(hs.Contains(uid)){ //比较Hashtable 表中是否有这个用户
  hs[uid] = DateTime.Now;//有用户的更新最后活动时间
}else{
  hs.Add(uid, DateTime.Now);
//没有的插入一个新的行
}

 DateTime t1 
= getUpdateTime();//取得保存的上次更新时间
            DateTime nowt = DateTime.Now;

            TimeSpan ts 
= nowt - t1;
            
if (ts.Minutes >2)
            {
                
//大于2分钟就把Hashtable表中的数据更新到数据库中
                
                   
foreach (DictionaryEntry o in hs)
                    {
                        Updata(o.Key, o.Value);
//更新到数据库方法
                    }            
                        hs.Clear();//清空Hashtable
                        setUpdateTime(DateTime.Now);//保存这次更新时间
                    

            }
           SaveCacheHs(hs);//保存到全局缓存里

}

 

 

posted on 2010-08-17 09:21  洋葱.Net  阅读(415)  评论(0编辑  收藏  举报