博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程安全的Generic Dictionary
阅读量:6404 次
发布时间:2019-06-23

本文共 1485 字,大约阅读时间需要 4 分钟。

 
只要不修改该集合,
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);
                }
            }
        }
 
本文转自 张善友 51CTO博客,原文链接:http://blog.51cto.com/shanyou/75069,如需转载请自行联系原作者
你可能感兴趣的文章
asp.net forms认证
查看>>
一帧图像的两种显示器建模方式
查看>>
Hadoop 公平调度器算法调度解析
查看>>
Linux Foundation(笔记)
查看>>
Java学习第二十五天
查看>>
vim配置
查看>>
ubuntu 把软件源修改为国内源和更新
查看>>
随机产生四则运算,导入导出文件
查看>>
位运算符
查看>>
winform自定义控件
查看>>
C#编码好习惯
查看>>
避其锋芒,侧翼出击。——司马亮创业回忆录(一)
查看>>
scope
查看>>
一起谈.NET技术,晚绑定场景下对象属性赋值和取值可以不需要PropertyInfo
查看>>
一起谈.NET技术,.Net Framework源代码中的模式之Prototype(原型模式)
查看>>
[shell 命令] find 查找文件
查看>>
windows下启动mysql服务的命令行启动和手动启动方法
查看>>
VTK三维点集轮廓凸包提取
查看>>
【概率论与数理统计】小结9-3 - 区间估计
查看>>
Golang性能调优入门
查看>>