C# 使用定时器和Dictionary 出现异常说集合已修改,可能无法执行枚举操作,求帮忙啊

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 使用定时器和Dictionary 出现异常说集合已修改,可能无法执行枚举操作,求帮忙啊相关的知识,希望对你有一定的参考价值。

定时器程序里,出现异常了

字典的定义

TCP新客户连接时添加元素

TCP客户端发送数据时,更新元素

对字典的操作都在上面了,不懂怎么会有这个异常的啊,小白求帮忙

有可能是多线程引起冲突,解决办法是使用线程安全的字典
ConcurrentDictionary<TKey, TValue> 类
http://msdn.microsoft.com/zh-cn/library/dd287191.aspx

另外在foreach里面不能再修改foreach的list,这是常识,你可以先克隆一个list来遍历。
参考技术A http://bbs.csdn.net/topics/390785078

参考技术B 你是不是循环错了?

C#中Dictionary的TryGetValue和Contains

一:前言

如果只是判断字典中某个值是否存在,使用Contains和TryGetValue都可以。如果需要判断是否存在之后再得到某个值,尽量使用TryGetValue

if (Dictionary.TryGetValue(key, out value))




if(Dictionary.ContainsKey(key))

	var value = Dictionary[key];

二:解释

先看一下TryGetValue源码实现

public bool TryGetValue(TKey key, out TValue value)
        
            if (key == null)
            
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
            
            lock(_lock)
            
                VerifyIntegrity();
                return TryGetValueWorker(key, out value);
            
        

        private bool TryGetValueWorker(TKey key, out TValue value)
        
            int entryIndex = FindEntry(key);
            if (entryIndex != -1)
            
                Object primary = null;
                Object secondary = null;
                _entries[entryIndex].depHnd.GetPrimaryAndSecondary(out primary, out secondary);
                // Now that we've secured a strong reference to the secondary, must check the primary again
                // to ensure it didn't expire (otherwise, we open a ---- where TryGetValue misreports an
                // expired key as a live key with a null value.)
                if (primary != null)
                
                    value = (TValue)secondary;
                    return true;
                
            
 
            value = default(TValue);
            return false;
        

再看一下ContainsKey和字典索引的实现

public bool ContainsKey(TKey key) 
            return FindEntry(key) >= 0;
        

        public TValue this[TKey key] 
            get 
                int i = FindEntry(key);
                if (i >= 0) return entries[i].value;
                ThrowHelper.ThrowKeyNotFoundException();
                return default(TValue);
            
            set 
                Insert(key, value, false);
            
        

想得到某个值,用TryGetValue只调用了1次FindEnty,而ContainKey判断还需要使用字典索引,一共需要调用2次FindEnty才能获取到值

以上是关于C# 使用定时器和Dictionary 出现异常说集合已修改,可能无法执行枚举操作,求帮忙啊的主要内容,如果未能解决你的问题,请参考以下文章

C#日常C#集合Dictionary获取第一个键值

C#日常C#泛型集合Dictionary<TKey, TValue>使用方法及泛型集合检查是否存在Key值

C#日常C#泛型集合Dictionary<TKey, TValue>使用方法及泛型集合检查是否存在Key值

C#基础 Dictionary存储自定义对象作为键值

C#日常C#集合Dictionary获取第一个键值

C#日常C#集合Dictionary获取第一个键值