執行緒安全的GenericDictionary
System.Collections.Generic.Dictionary<,>
錯誤出現的原因是程式碼中在列舉的過程中修改了集合,而造成了這個錯誤,修改後的程式碼如下:
只要不修改該集合,Dictionary 就可以同時支援多個閱讀器。即便如此,從頭到尾對一個集合進行列舉本質上並不是一個執行緒安全的過程。當出現列舉與寫訪問互相爭用這種極少發生的情況時,必須在整個列舉過程中鎖定集合。若要允許多個執行緒訪問集合以進行讀寫操作,則必須實現自己的同步。今天解決了使用Dictionary泛型類的時候出現一個錯誤 “System.InvalidOpervationException “集合已經修改,可能無法執行列舉操作””。原來的程式碼如下:
private void CheckingTimeout()
{
List<string> list = new List<string>();
lock (sessions)
{
foreach (string sessionKey in sessions.Keys)
{
if (sessions[sessionKey].IsTimeouted)
{
logger.Info(“會話 [“ + sessionKey + “] 超時“);
UnLoadSession(sessionKey);
list.Add(sessionKey);
}
}
foreach (string key in list)
{
sessions.Remove(key);
}
}
}
public void UnloadSession(string sessionID)
{
lock (sessions)
{
if (sessions.ContainsKey(sessionID))
{
db.Delete(GetSessionFromDatabase(sessionID));
dispatcher.UnregisterAllOutEventSubscriber(sessionID);
sessions.Remove(sessionID);
}
}
}
{
List<string> list = new List<string>();
lock (sessions)
{
foreach (string sessionKey in sessions.Keys)
{
if (sessions[sessionKey].IsTimeouted)
{
logger.Info(“會話 [“ + sessionKey + “] 超時“);
UnLoadSession(sessionKey);
list.Add(sessionKey);
}
}
foreach (string key in list)
{
sessions.Remove(key);
}
}
}
public void UnloadSession(string sessionID)
{
lock (sessions)
{
if (sessions.ContainsKey(sessionID))
{
db.Delete(GetSessionFromDatabase(sessionID));
dispatcher.UnregisterAllOutEventSubscriber(sessionID);
sessions.Remove(sessionID);
}
}
}
錯誤出現的原因是程式碼中在列舉的過程中修改了集合,而造成了這個錯誤,修改後的程式碼如下:
private void CheckingTimeout()
{
List<string> list = new List<string>();
lock (sessions)
{
foreach (string sessionKey in sessions.Keys)
{
if (sessions[sessionKey].IsTimeouted)
{
logger.Info(“會話 [“ + sessionKey + “] 超時“);
UnregisterSession(sessionKey);
list.Add(sessionKey);
}
}
foreach (string key in list)
{
sessions.Remove(key);
}
}
}
private void UnregisterSession(string sessionID)
{
lock (sessions)
{
if (sessions.ContainsKey(sessionID))
{
db.Delete(GetSessionFromDatabase(sessionID));
dispatcher.UnregisterAllOutEventSubscriber(sessionID);
}
}
}
{
List<string> list = new List<string>();
lock (sessions)
{
foreach (string sessionKey in sessions.Keys)
{
if (sessions[sessionKey].IsTimeouted)
{
logger.Info(“會話 [“ + sessionKey + “] 超時“);
UnregisterSession(sessionKey);
list.Add(sessionKey);
}
}
foreach (string key in list)
{
sessions.Remove(key);
}
}
}
private void UnregisterSession(string sessionID)
{
lock (sessions)
{
if (sessions.ContainsKey(sessionID))
{
db.Delete(GetSessionFromDatabase(sessionID));
dispatcher.UnregisterAllOutEventSubscriber(sessionID);
}
}
}
本文轉自 張善友 51CTO部落格,原文連結:http://blog.51cto.com/shanyou/75069,如需轉載請自行聯絡原作者
相關文章
- 【Java多執行緒】執行緒安全的集合Java執行緒
- 執行緒3--執行緒安全執行緒
- 執行緒安全和執行緒不安全理解執行緒
- 執行緒安全執行緒
- PHP的執行緒安全與非執行緒安全版本的區別PHP執行緒
- 多執行緒系列之 執行緒安全執行緒
- iOS 多執行緒之執行緒安全iOS執行緒
- iOS多執行緒之執行緒安全iOS執行緒
- Java執行緒(一):執行緒安全與不安全Java執行緒
- 多執行緒-以前的執行緒安全的類回顧執行緒
- 【多執行緒總結(二)-執行緒安全與執行緒同步】執行緒
- 什麼是執行緒安全和執行緒不安全執行緒
- 執行緒安全(二)執行緒
- Java執行緒安全Java執行緒
- Java - 執行緒安全Java執行緒
- STL容器的執行緒安全?執行緒
- 什麼時候執行緒不安全?怎樣做到執行緒安全?怎麼擴充套件執行緒安全的類?執行緒套件
- Java 多執行緒基礎(四)執行緒安全Java執行緒
- iOS多執行緒安全-13種執行緒鎖?iOS執行緒
- 多執行緒,你覺得你安全了?(執行緒安全問題)執行緒
- 執行緒安全性執行緒
- 多執行緒安全(一)執行緒
- 執行緒安全操作HashMap執行緒HashMap
- java執行緒安全LockJava執行緒
- EntityFrameworkDbContext執行緒安全FrameworkContext執行緒
- strerror執行緒安全分析Error執行緒
- 容器不是執行緒安全執行緒
- 併發程式設計之多執行緒執行緒安全程式設計執行緒
- 小度分享-【多執行緒工作及執行緒安全】執行緒
- 多執行緒與高併發(二)執行緒安全執行緒
- iOS開發基礎——執行緒安全(執行緒鎖)iOS執行緒
- 併發與多執行緒之執行緒安全篇執行緒
- 保障執行緒安全的設計執行緒
- ArrayList 的執行緒安全問題執行緒
- java中執行緒安全的集合Java執行緒
- 執行緒安全的單例模式執行緒單例模式
- [短文速讀 -5] 多執行緒程式設計引子:程式、執行緒、執行緒安全執行緒程式設計
- Java併發實戰一:執行緒與執行緒安全Java執行緒