『卧槽』意外发现了 Hashtable 的 foreach 用法 BUG
这段时间,公司项目中 遇到一个问题,最后查出: 是 Hashtable 的用法导致的。
1 private static void AutoCleanCache() 2 { 3 try 4 { 5 lock (m_HashCache.SyncRoot) 6 { 7 List<object> listKey = new List<object>(); 8 List<Tuple<string, DateTime, byte[]>> list = new List<Tuple<string, DateTime, byte[]>>(); 9 if (m_HashCache.Count >= MAXCACHE) 10 { 11 //foreach (KeyValuePair<object, object> pair in m_HashCache) //不能这样使用 Hashtable —— 可能会导致: 指定的转换无效 的异常 12 foreach (object key in m_HashCache.Keys) 13 { 14 object value = m_HashCache[key]; 15 var svg = key as string; 16 var bytes = value as Tuple<DateTime, byte[]>; 17 if (string.IsNullOrWhiteSpace(svg) || (bytes == null || bytes.Item2 == null || bytes.Item2.Length <= 0)) listKey.Add(key); 18 19 list.Add(new Tuple<string, DateTime, byte[]>(svg, (bytes == null ? DateTime.MinValue : bytes.Item1), (bytes == null ? null : bytes.Item2))); 20 } 21 } 22 23 List<Tuple<string, DateTime, byte[]>> list2 = Enumerable.ToList(list.OrderBy(x => x.Item2).Take(list.Count / 2)); 24 foreach (var item in list2) listKey.Add(item.Item1); 25 foreach (var key in listKey) m_HashCache.Remove(key); 26 27 listKey.Clear(); 28 list.Clear(); 29 list2.Clear(); 30 } 31 } 32 catch (Exception ex) 33 { 34 logger.Warn(ex); 35 } 36 }
代码很丑 —— 各位不要介意。
我们只看重点代码:
1 //foreach (KeyValuePair<object, object> pair in m_HashCache) //不能这样使用 Hashtable —— 可能会导致: 指定的转换无效 的异常 2 foreach (object key in m_HashCache.Keys)
结论:
Hashtable 不要 foreach KeyValuePair<object, object>
这下好了, 我这边 一堆底层代码 都遭殃了 ~