异步方法异常处理及FileSystemWatcher后台队列写入MySQL后续问题
针对FileSystemWatcher监控目录+MySQL入库的后续优化方案
嘿,很高兴你已经搞定了FileSystemWatcher独立运行和后台任务队列的核心逻辑!基于你现在的场景——监控目录新增文件并写入MySQL,我整理了几个开发者常会遇到的后续问题及解决思路,应该能帮到你:
1. 避免重复处理同一文件
FileSystemWatcher的Created事件偶尔会触发多次(比如部分编辑器保存文件时会先创建临时文件再替换),可以通过以下方式规避:
- 用
ConcurrentDictionary<string, DateTime>维护已处理文件的完整路径+最后修改时间戳缓存,处理前先校验 - 缓存可设置滑动过期时间,比如2小时,避免长期占用内存
- 也可以把已处理记录存到MySQL的一张临时表,查询更可靠
2. 数据库写入失败的重试与容错
网络波动或MySQL临时不可用会导致入库失败,建议给后台任务加上容错机制:
- 针对
MySqlException实现重试逻辑,比如最多重试3次,每次间隔1秒(也可以用Polly库简化实现) - 重试失败的任务放入死信队列,后续手动排查或定时触发重试
- 入库时开启事务,确保数据一致性:
using var connection = new MySqlConnection(_connectionString); await connection.OpenAsync(); using var transaction = await connection.BeginTransactionAsync(); try { var command = new MySqlCommand("INSERT INTO file_records (file_path, create_time) VALUES (@path, @time)", connection, transaction); command.Parameters.AddWithValue("@path", fileFullPath); command.Parameters.AddWithValue("@time", fileCreateTime); await command.ExecuteNonQueryAsync(); await transaction.CommitAsync(); } catch (Exception ex) { await transaction.RollbackAsync(); // 抛出异常触发重试逻辑 throw; }
3. 优化批量文件处理性能
如果目录短时间内涌入大量文件,后台队列可能出现积压:
- 用TPL Dataflow的
ActionBlock控制任务并发数,比如限制为5个并发,避免耗尽MySQL连接池 - 攒够一定数量的文件记录(比如50条)再执行批量插入,减少数据库IO次数:
// 批量插入示例 var values = string.Join(",", records.Select(r => $"('{r.FilePath}', '{r.CreateTime:yyyy-MM-dd HH:mm:ss}')")); var command = new MySqlCommand($"INSERT INTO file_records (file_path, create_time) VALUES {values}", connection); await command.ExecuteNonQueryAsync();
- 处理前先检查文件是否被占用:尝试以读写模式打开文件,捕获
IOException则等待几秒后重试
4. 增强监视器的稳定性
- 监听FileSystemWatcher的
Error事件,出现错误时自动重启监视器:
_watcher.Error += (sender, e) => { _logger.LogError(e.GetException(), "FileSystemWatcher发生异常"); RestartWatcher(); }; private void RestartWatcher() { _watcher.EnableRaisingEvents = false; _watcher.Dispose(); // 重新初始化监视器 InitializeWatcher(); }
- 定期校验监视器状态,比如每隔5分钟检查
EnableRaisingEvents是否为true,异常时自动恢复
5. 完善日志与监控
- 给每个处理环节添加详细日志:文件路径、触发时间、处理开始/结束时间、错误信息等,方便问题排查
- 暴露关键监控指标:队列积压数、成功入库数、失败数,便于实时掌握系统运行状态
内容的提问来源于stack exchange,提问作者Superleggera
相关产品推荐
相关产品推荐

