问题描述
我有一个同步的哈希表,我会定期从中删除一些条目。多个线程运行此代码。所以我锁定了整个foreach,但有时仍然会收到InvalidOperationException:在Hashtable.HashtableEnumerator.MoveNext()处修改了collection-即在foreach循环中。
我在做什么错?
I have a synchronized hashtable, from which I regularly remove some entries. Multiple threads run this code. So I lock the entire foreach, but I still sometimes get InvalidOperationException: Collection was modified ... at Hashtable.HashtableEnumerator.MoveNext() - i.e. in the foreach loop.What am I doing wrong? Isn't locking enough?
private static readonly Hashtable sessionsTimeoutData = Hashtable.Synchronized(new Hashtable(5000));
私有静态无效ClearTimedoutSessions()
{
List keysToRemove = new List();现在,
长= DateTime.Now.Ticks;
锁定(sessionsTimeoutData)
{
TimeoutData timeoutData;
foreach(sessionTimeoutData中的DictionaryEntry条目)
{
timeoutData =(TimeoutData)entry.Value;
if(现在-timeoutData.LastAccessTime> timeoutData.UserTimeoutTicks)
keysToRemove.Add((ulong)entry.Key);
}
}
foreach(keyToToMove中的长键)
sessionsTimeoutData.Remove(key);
}
private static void ClearTimedoutSessions(){ List keysToRemove = new List(); long now = DateTime.Now.Ticks; lock (sessionsTimeoutData) { TimeoutData timeoutData; foreach (DictionaryEntry entry in sessionsTimeoutData) { timeoutData = (TimeoutData)entry.Value; if (now - timeoutData.LastAccessTime > timeoutData.UserTimeoutTicks) keysToRemove.Add((ulong)entry.Key); } } foreach (ulong key in keysToRemove) sessionsTimeoutData.Remove(key);}
推荐答案
您要使用 SyncRoot
是同步的 Hashtable
的方法将锁定的对象:
You want to lock using SyncRoot
which is the object that the methods for a synchronized Hashtable
will lock on:
lock (sessionsTimeoutData.SyncRoot)
{
// ...
}
请参见:
通过集合进行枚举本质上不是线程安全的
过程。即使集合同步
,其他线程仍可以
修改该集合,这会导致
枚举器抛出异常。
为了保证
枚举期间的线程安全,您可以在整个
枚举期间锁定
集合,也可以捕获其他$ b $所做的更改导致的异常
以下代码示例显示
如何在整个
枚举期间使用
SyncRoot锁定集合:
The following code example shows how to lock the collection using the SyncRoot during the entire enumeration:
Hashtable myCollection = new Hashtable();
lock(myCollection.SyncRoot)
{
foreach (object item in myCollection)
{
// Insert your code here.
}
}
这篇关于InvalidOperationException:集合已修改-尽管锁定了集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!