我有一个同步哈希表,我定期从中删除一些条目。多个线程运行此代码。因此,我锁定了整个 foreach,但有时仍然会收到 InvalidOperationException: Collection was generated ... at Hashtable.HashtableEnumerator.MoveNext() - 即在 foreach 循环中。
我究竟做错了什么?锁定还不够吗?
private static readonly Hashtable sessionsTimeoutData = Hashtable.Synchronized(new Hashtable(5000));
私有静态无效 ClearTimedoutSessions()
{
列表要删除的键 = new List();
现在很长 = DateTime.Now.Ticks;
锁定(会话超时数据)
{
超时数据超时数据;
foreach(sessionTimeoutData 中的 DictionaryEntry 条目)
{
超时数据 = (超时数据)entry.Value;
if (现在 - timeoutData.LastAccessTime > timeoutData.UserTimeoutTicks)
keyToRemove.Add((ulong)entry.Key);
}
}
foreach(keysToRemove 中的 ulong 键)
sessionTimeoutData.Remove(key);
}
您想使用锁定SyncRoot
这是同步方法的对象Hashtable
将锁定:
lock (sessionsTimeoutData.SyncRoot)
{
// ...
}
See http://msdn.microsoft.com/en-us/library/system.collections.hashtable.synchronized.aspx http://msdn.microsoft.com/en-us/library/system.collections.hashtable.synchronized.aspx:
通过集合进行枚举是
本质上不是线程安全的
程序。即使是一个集合
同步后,其他线程仍然可以
修改集合,这会导致
枚举器抛出异常。
保证期间的线程安全
枚举,您可以锁定
整个过程中采集
枚举或捕获异常
由其他人所做的更改引起的
线程。
下面的代码示例展示了如何
使用锁定集合
整个过程中SyncRoot
枚举:
Hashtable myCollection = new Hashtable();
lock(myCollection.SyncRoot)
{
foreach (object item in myCollection)
{
// Insert your code here.
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)