Я подозреваю проблему со старой версией ObjectBuilder, которая когда-то была частью проекта расширения WCSF, а тем временем переместилась в Unity. Я не уверен, на правильном ли я пути или нет, поэтому я надеюсь, что у кого-то есть более компетентные навыки безопасности потоков, чтобы объяснить, может ли это быть проблемой или нет.
Я использую эту (устаревшую) реализацию ObjectBuilder в веб-приложении ASP.Net WCSF и редко вижу в журналах, что ObjectBuilder жалуется на то, что определенное свойство класса не может быть введено по какой-либо причине, проблема всегда в том, что это свойство ни в коем случае нельзя вводить. Собственность и класс постоянно меняются. Я проследил код до метода, в котором словарь используется для хранения информации о том, обрабатывается ли свойство ObjectBuilder или нет.
Мой вопрос в основном сводится к следующему: есть ли проблема безопасности потоков в следующем коде, которая может привести к тому, что ObjectBuilder получит несогласованные данные из своего словаря?
Класс, который содержит этот код (ReflectionStrategy.cs), создается как Singleton, поэтому все запросы к моему веб-приложению используют этот класс для создания объектов представления/страницы. Его словарь — это приватное поле, используемое только в этом методе и объявленное следующим образом:
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;
}