2

我怀疑旧版本的 ObjectBuilder 存在问题,它曾经是 WCSF 扩展项目的一部分,同时移入 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;
}
4

1 回答 1

1
  1. 如果您运行大量的类/成员,哈希码的使用看起来会出现问题,就像您提到的单例方法一样。
  2. 双锁在旧锁中是完全奇怪的(在所有情况下只有一个线程进入整个部分)。请注意,首先锁定肯定会损害性能。这是一种交易,请注意,他们创建一个副本以避免在读取列表时对其进行修改。
于 2013-06-29T00:35:25.083 回答