集合已经修改,枚举操作可能不会执行.

M1chael 2006-08-30 01:30:50

晕,昨天早早的结帖了,想着不会再出现问题了,结果又出现了.代码如下:

[WebMethod]
public UserOnlineTimestamp[] CurrentOnlineUser()
{
ArrayList al = new ArrayList();
Hashtable syncdHt = Hashtable.Synchronized(Application["Passport_UserLoginTimeStamp"] as Hashtable);
lock(syncdHt.SyncRoot)
{
foreach (string key in syncdHt.Keys)
{
try
{
UserOnlineTimestamp userOnlineTimestamp = new UserOnlineTimestamp();
userOnlineTimestamp.UserID = key.ToString();
userOnlineTimestamp.OnlineTimestamp = Convert.ToDateTime(syncdHt[key]);
userOnlineTimestamp.location = GetUserOnlineLocation(key.ToString());
al.Add(userOnlineTimestamp);
}
catch (Exception ex)
{
continue;
}
}
}
return al.ToArray(typeof(UserOnlineTimestamp)) as UserOnlineTimestamp[];
}

请各位大侠帮偶分析下? 到底该怎么解决?
...全文
165 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
M1chael 2006-08-31
  • 打赏
  • 举报
回复
Hashtable 可以同时支持一个编写器和多个阅读器。若要支持多个编写器,则所有操作只能通过此包装完成。

通过集合枚举在本质上不是一个线程安全的过程。甚至在对集合进行同步处理时,其他线程仍可以修改该集合,这会导致枚举数引发异常。若要在枚举过程中保证线程安全,可以在整个枚举过程中锁定集合,或者捕捉由于其他线程进行的更改而引发的异常。

[Visual Basic, C#] 下面的代码示例显示如何在整个枚举过程中使用 SyncRoot 锁定集合:

[C#]
Hashtable myCollection = new Hashtable();
lock( myCollection.SyncRoot ) {
foreach ( Object item in myCollection ) {
// Insert your code here.
}
}

按照MSDN的说法使用SynRoot锁定就应该没问题了。


M1chael 2006-08-31
  • 打赏
  • 举报
回复

lookfeng() 的意思是,在修改Application["Passport_UserloginTimeStamp"]的时候也对它进行lock? 而仅仅在foreach的时候
Hashtable syncdHt = Hashtable.Synchronized(Application["Passport_UserLoginTimeStamp"] as Hashtable);
lock(syncdHt.SyncRoot)

这样是不够的 ?
ilove8 2006-08-31
  • 打赏
  • 举报
回复
没人顶,顶yi下...
greennetboy 2006-08-31
  • 打赏
  • 举报
回复
lock(syncdHt.Keys)

试试
lookfeng 2006-08-31
  • 打赏
  • 举报
回复
你贴的代码没有大问题,关键是你什么时候修改
Application["Passport_UserLoginTimeStamp"]的

在修改时同样要锁定:
lock ((Application["Passport_UserLoginTimeStamp"] as Hashtable).SyncRoot)

光在foreach时锁定是没用的。
M1chael 2006-08-30
  • 打赏
  • 举报
回复

能不能麻烦说的详细点? 我把Application["Passport_UserOnlineTimeStamp"]作为一个同步的
Hash表,然后再lock, 再在遍历的时候捕捉异常,结果还是会报错,就是不太懂错在哪儿了.

你说的自己做个Hash表继承NameObjectCollectionBase,定义个item元素,我不太明白.
lxwin01 2006-08-30
  • 打赏
  • 举报
回复
自己做个Hash表,继承NameObjectCollectionBase
定义一个item元素
public DictionaryFieldInfo this[int index]
{
get
{
df.Key=this.BaseGetKey(index);
df.Value=(IFieldInfo)this.BaseGet(index);
return df;
}
}
当然这里的DictionaryFieldInfo是我自己的对象,通过下标去访问。
M1chael 2006-08-30
  • 打赏
  • 举报
回复

没人顶,我自己顶下...

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧