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

前端之家收集整理的这篇文章主要介绍了c# – InvalidOperationException:修改了集合 – 虽然锁定了集合前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个同步哈希表,我定期从中删除一些条目.多个线程运行此代码.所以我锁定了整个foreach,但我仍然有时会得到InvalidOperationException:Collection被修改了……在Hashtable.HashtableEnumerator.MoveNext() – 即在foreach循环中. @H_502_2@我究竟做错了什么?锁不够?
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@H_502_2@ intrinsically not a thread-safe@H_502_2@ procedure. Even when a collection is@H_502_2@ synchronized,other threads can still@H_502_2@ modify the collection,which causes@H_502_2@ the enumerator to throw an exception.@H_502_2@ To guarantee thread safety during@H_502_2@ enumeration,you can either lock the@H_502_2@ collection during the entire@H_502_2@ enumeration or catch the exceptions@H_502_2@ resulting from changes made by other@H_502_2@ threads.

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

06001

猜你在找的C#相关文章