使用Hashtable维护在线用户时的一个小错误。
时间:2010-08-17 来源:aoecn
有一个网站(成长家园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锁住整个操作方法,修改后代码如下:
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);//保存到全局缓存里
}
相关阅读 更多 +