我为一个小项目创建了一个简单的验证过程。验证规则被创建为类的属性的属性。
我有一个需要传递类类型的静态类。该方法将首先检查给定类的规则集是否已经在字典中,否则,它将使用反射来遍历每个属性。
使用这种方法会有任何问题吗?我担心在多线程环境中访问它可能会导致一些问题。
public static class Validator
{
private static Dictionary<Type, ValidationRulesCollection> _validationRules = new Dictionary<Type, ValidationRulesCollection>();
public static ValidationRulesCollection GetValidationRules(object obj)
{
return GetValidationRules(obj.GetType());
}
public static ValidationRulesCollection GetValidationRules(Type t)
{
ValidationRulesCollection rules = null;
/* Check if the centralized rules repository already contains the rules for this class type */
if (_validationRules.ContainsKey(t) == true)
{
rules = _validationRules[t];
}
else
{
/* Using reflection, get the list of properties for the class type */
PropertyInfo[] properties = t.GetProperties();
if (properties != null)
{
/* Iterate through each property info and check if it contains a validation rule */
ValidationAttribute[] attribs = null;
foreach (PropertyInfo property in properties)
{
/* For each property, check if it contains a validation rule */
attribs = (ValidationAttribute[])property.GetCustomAttributes(typeof(ValidationAttribute), true);
if (attribs != null)
{
foreach (ValidationAttribute attrib in attribs)
{
if (rules == null)
rules = new ValidationRulesCollection();
/* Add the validation rule to the collection */
rules.Add(new ValidationRule(property, attrib));
}
}
}
}
/* Add the rules collection to the centralized rules repository */
if (rules.Count > 0)
_validationRules.Add(t, rules);
else
throw new ArgumentNullException("The type " + t.ToString() + " does not have any ValidationAttributes");
}
return rules;
}
public static ValidationRulesCollection Validate(object obj)
{
/* Get the Validation Rules */
ValidationRulesCollection rules = GetValidationRules(obj);
/* Validate the rules */
foreach (ValidationRule rule in rules)
{
rule.Validate(obj);
}
return rules;
}
}
答案 0 :(得分:3)
Dictionary
不是线程安全的。你的方法GetValidationRules
正在阅读和编写它。如果多个线程调用此方法,则字典数据可能会损坏。为避免这种情况,请添加一个涵盖所有字典方法调用的lock(...){ ... }
。
答案 1 :(得分:2)
这可能会让您在多线程环境中遇到麻烦。通常,Dictionary<K,V>
类不是线程安全的。 Beyound数据损坏或正确性问题,在极少数情况下,如果一个线程在另一个线程上调整字典时遇到字典,则可能会出现线程陷入循环,占用100%CPU的情况。这在我的生产网络应用程序中发生过一次 - 调试并不是一件有趣的事情。
您可以锁定方法,也可以使用ConcurrentDictionary<K,V>
。
请注意,我们可以用不同的方式定义“线程安全”。如果您希望查找属性和属性的整个操作是原子的,则应该锁定该方法。但请注意,这会在应用程序中引入相当多的锁定,可能会损害性能。如果你可以在竞争条件下两次潜在地完成工作,并且只需要确保字典行为正确,那么ConcurrentDictionary就是你的选择。