优化含25万+行与357条验证规则的大文件处理架构问询
针对25万行数据+357条验证规则的高效架构方案
一、核心架构:规则抽象+统一执行引擎
1. 抽象验证规则接口
将所有验证规则统一实现一个接口,消除硬编码的规则调用,同时保证规则的一致性:
public interface IValidationRule { // 针对单条数据的验证方法(推荐单遍历模式) ValidationResult ValidateSingle(ProcessedRow row); string RuleCode { get; } string ErrorMessage { get; } }
2. 实现规则类(含正则预编译优化)
每个规则对应一个实现类,预编译正则表达式(避免每次验证重复编译,大幅提升性能):
public class RuleA : IValidationRule { public string RuleCode => "RULE_A"; public string ErrorMessage => "Validation Error"; // 静态预编译正则,复用实例 private static readonly Regex _regexA = new Regex(@"\bA12[01346]\b", RegexOptions.Compiled | RegexOptions.CultureInvariant); private static readonly Regex _regexB = new Regex(@"\bB45[0-9]\b", RegexOptions.Compiled | RegexOptions.CultureInvariant); private static readonly Regex _regexC = new Regex(@"\bC78[0-9]\b", RegexOptions.Compiled | RegexOptions.CultureInvariant); public ValidationResult ValidateSingle(ProcessedRow row) { if (_regexA.IsMatch(row.ALL_CODES) && (_regexB.IsMatch(row.ALL_CODES) || _regexC.IsMatch(row.ALL_CODES))) { return new ValidationResult { ID = row.ID, GROUP_ID = row.GROUP_ID, ERROR = ErrorMessage, ERROR_REF = RuleCode }; } return null; } }
3. 批量执行规则
通过规则容器收集所有规则实例,实现批量执行,避免手写357次规则调用:
// 应用启动时初始化规则容器(可结合依赖注入) var validationRules = new List<IValidationRule> { new RuleA(), new RuleB(), // ... 其他355条规则 }; // 执行所有验证(单遍历模式:仅遍历25万行一次,每行执行所有规则检查) var allValidationResults = new List<ValidationResult>(); foreach (var row in processedData) { foreach (var rule in validationRules) { var result = rule.ValidateSingle(row); if (result != null) { allValidationResults.Add(result); } } }
二、关键性能优化
1. 优先使用「单遍历多规则」模式
原方案中每个规则单独遍历25万行,357条规则会产生357次全量遍历,改为单遍历模式后仅需1次全量遍历,性能提升显著。
2. 正则表达式预编译
所有正则表达式通过RegexOptions.Compiled预编译为IL代码,避免每次IsMatch时重复解析正则,平均可提升30%-50%的正则匹配速度。
3. 并行执行规则(可选)
若规则之间无依赖,可通过并行执行进一步缩短验证时间(注意WPF需在后台线程执行):
var allValidationResults = new ConcurrentBag<ValidationResult>(); Parallel.ForEach(processedData, row => { foreach (var rule in validationRules) { var result = rule.ValidateSingle(row); if (result != null) { allValidationResults.Add(result); } } });
4. 数据加载优化
取消重复加载操作:原代码中同时加载DataTable和sourceData,仅保留sourceData并直接映射为ProcessedRow,减少内存占用和IO开销。
三、可维护性扩展:配置化规则
针对357条规则的维护痛点,可将规则配置(正则表达式、错误信息、规则编码)存入JSON/XML文件,实现无代码修改即可调整规则:
1. 规则配置文件示例(JSON)
[ { "RuleCode": "RULE_A", "ErrorMessage": "Validation Error", "RequiredPatterns": ["\\bA12[01346]\\b"], "AnyPatterns": ["\\bB45[0-9]\\b", "\\bC78[0-9]\\b"] }, { "RuleCode": "RULE_B", "ErrorMessage": "Invalid Code Format", "RequiredPatterns": ["\\bX99[0-5]\\b"] } ]
2. 通用规则实现类
public class ConfigurableRegexRule : IValidationRule { public string RuleCode { get; } public string ErrorMessage { get; } private readonly List<Regex> _requiredRegexes; private readonly List<Regex> _anyRegexes; public ConfigurableRegexRule(string ruleCode, string errorMessage, List<string> requiredPatterns, List<string> anyPatterns) { RuleCode = ruleCode; ErrorMessage = errorMessage; _requiredRegexes = requiredPatterns.Select(p => new Regex(p, RegexOptions.Compiled | RegexOptions.CultureInvariant)).ToList(); _anyRegexes = anyPatterns.Select(p => new Regex(p, RegexOptions.Compiled | RegexOptions.CultureInvariant)).ToList(); } public ValidationResult ValidateSingle(ProcessedRow row) { bool allRequiredMatch = _requiredRegexes.All(r => r.IsMatch(row.ALL_CODES)); bool anyMatch = _anyRegexes.Count == 0 || _anyRegexes.Any(r => r.IsMatch(row.ALL_CODES)); if (allRequiredMatch && anyMatch) { return new ValidationResult { ID = row.ID, GROUP_ID = row.GROUP_ID, ERROR = ErrorMessage, ERROR_REF = RuleCode }; } return null; } }
3. 从配置加载规则
// 读取配置文件并初始化规则 var ruleConfigs = JsonSerializer.Deserialize<List<RuleConfig>>(File.ReadAllText("validationRules.json")); var validationRules = ruleConfigs.Select(config => new ConfigurableRegexRule( config.RuleCode, config.ErrorMessage, config.RequiredPatterns, config.AnyPatterns ?? new List<string>() )).ToList();
四、WPF UI线程隔离
所有耗时操作(数据加载、验证)必须放到后台线程,避免UI冻结:
private async void StartValidation_Click(object sender, RoutedEventArgs e) { StartValidationBtn.IsEnabled = false; try { var filePath = openFileDialog.FileName; // 后台加载并映射数据 var processedData = await Task.Run(() => { var sourceData = ReadExcelDirect(filePath); return sourceData.Select(item => new ProcessedRow { // 映射属性 }).ToList(); }); // 后台执行验证 var validationResults = await Task.Run(() => { var results = new List<ValidationResult>(); foreach (var row in processedData) { foreach (var rule in validationRules) { var result = rule.ValidateSingle(row); if (result != null) { results.Add(result); } } } return results; }); // 回到主线程更新UI Dispatcher.Invoke(() => { ValidationResultsDataGrid.ItemsSource = validationResults; }); } catch (Exception ex) { MessageBox.Show($"操作失败:{ex.Message}"); } finally { StartValidationBtn.IsEnabled = true; } }
内容的提问来源于stack exchange,提问作者MANSI
相关产品推荐
相关产品推荐

