我究竟做错了什么?锁不够?
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); }
解决方法
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