c# – InvalidOperationException:修改了集合 – 虽然锁定了集合

前端之家收集整理的这篇文章主要介绍了c# – InvalidOperationException:修改了集合 – 虽然锁定了集合前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个同步哈希表,我定期从中删除一些条目.多个线程运行此代码.所以我锁定了整个foreach,但我仍然有时会得到InvalidOperationException:Collection被修改了……在Hashtable.HashtableEnumerator.MoveNext() – 即在foreach循环中.
我究竟做错了什么?锁不够?
private static readonly Hashtable sessionsTimeoutData = Hashtable.Synchronized(new Hashtable(5000));

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锁定,SyncRoot是同步Hashtable的方法将锁定的对象:
lock (sessionsTimeoutData.SyncRoot)
{
    // ...
}

http://msdn.microsoft.com/en-us/library/system.collections.hashtable.synchronized.aspx

Enumerating through a collection is
intrinsically not a thread-safe
procedure. Even when a collection is
synchronized,other threads can still
modify the collection,which causes
the enumerator to throw an exception.
To guarantee thread safety during
enumeration,you can either lock the
collection during the entire
enumeration or catch the exceptions
resulting from changes made by other
threads.

The following code example shows how
to lock the collection using the
SyncRoot during the entire
enumeration:

06001

猜你在找的C#相关文章