我查询远程服务,一次接收一批100个产品,并继续这样做,直到不再有批次为止。我将这100个产品重新映射到我自己的产品对象,我希望验证并一次保存到数据库中。如果没有验证我记录错误并继续其余的。一旦前100个处理完毕,我就去下一批100个。总共大约有5000个。
我在浏览网站后看到的问题是 Validator.TryValidateObject 似乎需要更长时间才能运行。第一批1000分钟需要10分钟,第二批1000分钟需要20分钟,第三批1000分钟需要30分钟。所以每次看起来要花费10分钟。
Product类有一个伙伴类ProductValidation,其中包含用于验证的相应数据注释。我叫product.IsValid()。
public class Product{
public bool IsValid()
{
return this.IsValid<Product, ProductValidation>();
}
}
使用以下代码:
public static bool IsValid<T, U>(this T obj)
{
if (typeof(T) != typeof(U))
{
TypeDescriptor.AddProviderTransparent(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(T), typeof(U)), typeof(T));
}
var validationContext = new ValidationContext(obj, null, null);
var validationResults = new List<ValidationResult>();
//The line below slows everything down. If commented out all is fine
Validator.TryValidateObject(obj, validationContext, validationResults, true);
if (validationResults.Count > 0)
return false;
else
return true;
}
为什么上述情景会以指数方式放缓?就像验证器每次都重新验证所有对象一样。
答案 0 :(得分:2)
您描述的是二次运行时间,其中每单位工作成本随着完成的工作量线性增加。
我可以看到的最可能的解释是AddProviderTransparent
扩展了一个具有线性搜索时间的列表,要么是因为它使用线性搜索,要么是因为哈希冲突和线性搜索通过桶。 / p>
如果为每个工作单元添加一个新提供程序,并为每个单元处理整个提供程序列表,那么您将获得二次运行时。
不是在每次调用时扩展提供者列表,而是仅在列表中尚未包含所需的提供者时才这样做。您可以使用HashSet<Pair<Type, Type>>
来记住您已添加的T, U
对。