加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 08:05:42 所属栏目:百科 来源:网络整理
导读:我有一个同步哈希表,我定期从中删除一些条目.多个线程运行此代码.所以我锁定了整个foreach,但我仍然有时会得到InvalidOperationException:Collection被修改了……在Hashtable.HashtableEnumerator.MoveNext() – 即在foreach循环中. 我究竟做错了什么?锁不
我有一个同步哈希表,我定期从中删除一些条目.多个线程运行此代码.所以我锁定了整个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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读