这个ObjectBuilder代码中是否存在线程安全问题?

时间:2013-06-26 07:45:36

标签: asp.net multithreading thread-safety wcsf objectbuilder

我怀疑旧版本的ObjectBuilder存在问题,该版本曾经是WCSF Extension项目的一部分,同时也进入了Unity。我不确定我是否采用正确的方式,所以我希望有人能够提供更有能力的线程安全技能来解释这是否是一个问题。

我在ASP.Net WCSF Web应用程序中使用这个(过时的)ObjectBuilder实现,很少我在日志中看到ObjectBuilder抱怨由于某种原因无法注入类的特定属性,问题始终存在永远不应该注入这个属性。财产和阶级不断变化。我将代码追溯到一种方法,其中使用字典来保存信息,无论属性是否由ObjectBuilder处理。

我的问题基本上归结为:以下代码中是否存在线程安全问题,这可能导致ObjectBuilder从其字典中获取不一致的数据?

保存此代码的类(ReflectionStrategy.cs)创建为Singleton,因此对我的Web应用程序的所有请求都使用此类来创建其视图/页面对象。它的字典是一个私有字段,仅在此方法中使用并声明如下:

private Dictionary<int, bool> _memberRequiresProcessingCache = new Dictionary<int, bool>();

private bool InnerMemberRequiresProcessing(IReflectionMemberInfo<TMemberInfo> member)
{
    bool requires;

    lock (_readLockerMrp)
    {
        if (!_memberRequiresProcessingCache.TryGetValue(member.MemberInfo.GetHashCode(), out requires))
        {
            lock (_writeLockerMrp)
            {
                if (!_memberRequiresProcessingCache.TryGetValue(member.MemberInfo.GetHashCode(), out requires))
                {
                    requires = MemberRequiresProcessing(member);
                    _memberRequiresProcessingCache.Add(member.MemberInfo.GetHashCode(), requires);
                }
            }
        }
    }
    return requires;
}  

上面的代码不是Codeplex上可以找到的最新版本,但我仍然想知道它是否是我的ObjectBuilder异常的原因。在我们发言时,我正在进行更新,以便将旧代码替换为最新版本。这是最新的实现,遗憾的是我无法找到任何有关更改的信息。可能是一个错误,可能是为了表现......

private bool InnerMemberRequiresProcessing(IReflectionMemberInfo<TMemberInfo> member)
{
  bool requires;

  if (!_memberRequiresProcessingCache.TryGetValue(member.MemberInfo, out requires))
  {
    lock (_writeLockerMrp)
    {
      if (!_memberRequiresProcessingCache.TryGetValue(member.MemberInfo, out requires))
      {
        Dictionary<TMemberInfo, bool> tempMemberRequiresProcessingCache =
          new Dictionary<TMemberInfo, bool>(_memberRequiresProcessingCache);
        requires = MemberRequiresProcessing(member);
        tempMemberRequiresProcessingCache.Add(member.MemberInfo, requires);
        _memberRequiresProcessingCache = tempMemberRequiresProcessingCache;
      }
    }
  }
  return requires;
}

1 个答案:

答案 0 :(得分:1)

  1. 如果您运行大量的类/成员,哈希代码的使用会出现问题,就像您提到的单例方法一样。
  2. 旧锁中的双锁是完全奇怪的(在所有情况下只有一个线程进入整个部分)。请注意,锁定作为第一件事肯定会伤害性能。这是一个交易,请注意,他们创建一个副本,以避免在读取时修改列表。