FileSystemWatcher 默认配置下常因路径非法、权限不足、NotifyFilter与Filter不匹配、缓冲区溢出或未设IncludeSubdirectories而失效;须用本地绝对路径、合理设置过滤器、启用子目录监听、增大缓冲区并强引用防止GC回收。
FileSystemWatcher 能用,但默认配置下大概率不工作——不是代码写错了,而是路径、权限、生命周期或缓冲区这四点卡住了。
Path 必须是本地绝对路径,UNC 和映射盘符直接失效
常见现象:
也设了,事件回调一个没触发。根本原因常是路径非法。
不能是相对路径(如
)、UNC 路径(如
)或网络映射盘符(如
),否则静默失败,无异常
必须用本地物理路径,例如
;可用
转换相对路径确保合规
若程序以管理员身份运行,而目标目录属普通用户(如
),UAC 隔离可能导致监听被拦截
避免监控系统路径(如
),部分 Windows 版本会直接屏蔽通知
NotifyFilter 和 Filter 不协同,事件就“看不见”
控文件名匹配,
控变更类型——两者缺一不可,且默认值极窄。
设了
却没调
,连重命名都收不到:因为默认只含
,不含
关心内容修改?用
或
要捕获新建/删除/重命名?组合写:
跳过编辑器临时文件?在事件处理器里加判断:
Changed 事件触发太早?防抖和线程安全必须做
大文件写入时
常在写完前触发,直接读会抛
(“正由另一进程使用”)。
C知道
CSDN推出的一款AI技术问答工具
下载
别在事件回调里立刻打开文件——先加
,再检查
是否稳定
更可靠方式:尝试以独占模式打开
,捕获
就说明还在写
事件回调运行在线程池线程上,更新 WinForm/WPF 控件前必须用
或
禁止在回调里做耗时操作(解析 JSON、上传 HTTP),否则事件队列堆积,后续通知直接丢失
服务或后台程序中失效?GC 回收和目录校验是主因
Windows Service 或长时间运行的后台任务里,
经常“突然不响”,基本不是它坏了,而是被回收或启动条件不满足。
必须用
强引用,否则 GC 可能在任意时刻回收对象
启动前务必校验目录存在:
必须在所有属性(
、
、
等)设置完毕后最后调用,否则初始事件可能漏掉
缓冲区溢出是隐形杀手:解压、Git checkout 等批量操作易填满默认 8KB 缓冲区,导致静默丢事件;可设
,但治标不治本
最易被忽略的是:递归监听子目录必须显式设
,默认只看一级——这个开关不打开,
的修改永远进不了你的
回调。
EnableRaisingEvents = truePath"./logs"r"\servershare""Z:\data"r"C:MyAppData"Path.GetFullPath()C:UsersAliceDocumentsC:WindowsFilterNotifyFilterFilter = "*.log"NotifyFilterFileName | DirectoryNameLastWriteNotifyFilters.LastWriteNotifyFilters.SizeNotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.CreationTimeif (e.Name.StartsWith("~$") || e.Name.EndsWith(".tmp")) return;ChangedIOExceptionawait Task.Delay(100)File.GetLastWriteTimeUtc(path)File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None)IOExceptionControl.InvokeDispatcher.BeginInvokeFileSystemWatcherprivate readonly FileSystemWatcher _watcherif (!Directory.Exists(path)) throw new InvalidOperationException($"监控路径不存在: {path}");EnableRaisingEvents = truePathFilterIncludeSubdirectoriesInternalBufferSize = 64 * 1024IncludeSubdirectories = trueC:logssubpp.logChanged