首页 > 其他分享 >线程安全的Generic Dictionary

线程安全的Generic Dictionary

时间:2022-10-24 16:09:44浏览次数:72  
标签:string Dictionary sessions Generic list 枚举 sessionID sessionKey 线程

 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);
}
}
}

错误出现的原因是代码中在枚举的过程中修改了集合,而造成了这个错误,修改后的代码如下:
 

  

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);
}
}
}



标签:string,Dictionary,sessions,Generic,list,枚举,sessionID,sessionKey,线程
From: https://blog.51cto.com/shanyou/5790040

相关文章

  • 在线程中更新UI
    为了更新UI线程,在新线程中用this.Invoke来更新UI上控件的值。其实这背后是有异常的(有可能会在vs中报出来),因为当你关闭窗体时,this已经不存在了,但访问this.Invoke在新的线程......
  • Java-JVM调优jstack找出最耗cpu的线程&定位问题代码
    Java-JVM调优jstack找出最耗cpu的线程&定位问题代码 https://blog.csdn.net/shasiqq/article/details/109801683   JVM调优jstack找出最耗cpu的线程&定位问题代码......
  • XML Serializable Generic Dictionary
       .net2.0泛型Dictionary不支持XMLserializable. 下面是一个实现IXmlSerializable接口实现支持Serialize的泛型集合.Dictionary 。Dictionary<TKey,TValue>......
  • 进程与线程的区别
    进程是资源分配的最小单位,线程是CPU调度的最小单位进程和线程的根本区别是进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。另外区别还有资源......
  • 进程与线程的区别
    进程和线程的区别1、首先是定义进程:是执行中一段程序,即一旦程序被载入到内存中并准备执行,它就是一个进程。进程是表示资源分配的的基本概念,又是调度运行的基本单位,是系统......
  • 进程与线程
    本章内容进程和线程的概念并行和并发的概念线程基本应用2.1进程与线程进程程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据......
  • Java多线程(3):ThreadPool(上)
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~ 开完一趟车完整的过程是启动、行驶和停车,但老司机都知道,真正费油的不是行驶,而是长时间的怠速、频繁地踩刹车等动作。因......
  • Java生产者消费者问题-多线程-线程同步-线程安全-线程通信
    packageA_ShangGuiGu.Thread.ThreadTest;/***生产者消费者问题:生产者(Producer)将商品(commodity)交给商店(Shop),消费者(Consumer)进行消费*商店里的商品数量上限为20......
  • wait和notify线程通信
    packageA_ShangGuiGu.Thread.ThreadTest;/***线程通信的实例:两个线程交替打印1-100,一人一次*涉及到的方法:*wait():调用wait()方法会使得调用该方法的线程进入阻塞状态。......
  • 进程与线程的联系与区别
    进程 一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,一个进程可以有多个线程,比如在Windows系统中,一个运行的xx.exe就是一个进程。   线程进......