这问题是我的错还是.Net的bug

本文分析了在并发环境中使用C# Dictionary时遇到的未将对象引用设置到对象的实例异常,并提供了一种通过双重检查锁定模式来解决此问题的方法。

在使用Dictionary<T,T1>的Add方法,内部竟然抛出"未将对象引用设置到对象的实例。",这个错误只有在并发的时候出现。

代码如下:

 

ContractedBlock.gifExpandedBlockStart.gifCode
        internal static string GetParamName()
        {
            
                
int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
                
if (!mSeed.ContainsKey(id))
                    mSeed.Add(id, 
new ParamNameSeed());
                ParamNameSeed pns 
= mSeed[id];
                
if (pns.Value > 100)
                    pns.Value 
= 0;
                
else
                    pns.Value
++;
                
return "p" + pns.Value;
          
        }
        
static Dictionary<int, ParamNameSeed> mSeed = new Dictionary<int, ParamNameSeed>();

 

抛出错误的是:

mSeed.Add(id, new ParamNameSeed());

错误情况:

未将对象引用设置到对象的实例。
在 System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
在 System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
在 Smark.Data.Expression.GetParamName() 位置 F:\Projects\SmarkProject\Smark.Data\Expression.cs:行号 84
在 Smark.Data.FieldInfo.Eq(Object value) 位置 F:\Projects\SmarkProject\Smark.Data\Expression.cs:行号 133
在 Smark.Data.FieldInfo.op_Equality(FieldInfo field, Object value) 位置 F:\Projects\SmarkProject\Smark.Data\Expression.cs:行号 343

修改代码如下该错误暂时没有出现:

 

ContractedBlock.gifExpandedBlockStart.gifCode
        internal static string GetParamName()
        {

            Dictionary
<int, ParamNameSeed> seedTable = GetSeedTable();    
            
int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
            
if (!seedTable.ContainsKey(id))
                seedTable.Add(id, 
new ParamNameSeed());
                ParamNameSeed pns 
= mSeed[id];
                
if (pns.Value > 100)
                    pns.Value 
= 0;
                
else
                    pns.Value
++;
                
return "p" + pns.Value;
          
        }
        
static Dictionary<int, ParamNameSeed> mSeed =null//new Dictionary<int, ParamNameSeed>();
        static object mLockSeed = new object();
        
static Dictionary<int, ParamNameSeed> GetSeedTable()
        {
            
if(mSeed==null)
            {
                
lock (mLockSeed)
                {
                    
if (mSeed == null)
                        mSeed 
= new Dictionary<int, ParamNameSeed>();
                }
            }
            
return mSeed;
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值