FileSystemWatcher 源码执行流程
先注册绑定事件 FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(); fileSystemWatcher.Path = Directory.GetCurrentDirectory(); fileSystemWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; //文件类型,支持通配符,“*.txt”只监视文本文件 fileSystemWatcher.Filter = "*.*"; // 监控的文件格式 fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.Changed += new FileSystemEventHandler(OnProcess); fileSystemWatcher.Created += new FileSystemEventHandler(OnProcess); fileSystemWatcher.Renamed += new RenamedEventHandler(OnRenamed); fileSystemWatcher.Deleted += new FileSystemEventHandler(OnProcess); //表示当前的路径正式开始被监控,一旦监控的路径出现变更,FileSystemWatcher 中的指定事件将会被触发。 fileSystemWatcher.EnableRaisingEvents = true;//启动监控 1 Console.ReadLine(); //绑定方法 private static void OnProcess(object source, FileSystemEventArgs e) { if (e.ChangeType == WatcherChangeTypes.Created) { OnCreated(source, e); } else if (e.ChangeType == WatcherChangeTypes.Changed) { OnChanged(source, e); } else if (e.ChangeType == WatcherChangeTypes.Deleted) { OnDeleted(source, e); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 1 F:\SourceCode\Net\Net8\runtime\src\libraries\System.IO.FileSystem.Watcher\src\System\IO\FileSystemWatcher.cs EnableRaisingEvents 属性这里 private void StartRaisingEventsIfNotDisposed() { //Cannot allocate the directoryHandle and the readBuffer if the object has been disposed; finalization has been suppressed. ObjectDisposedException.ThrowIf(_disposed, this ); StartRaisingEvents(); } 1.1 F:\SourceCode\Net\Net8\runtime\src\libraries\System.IO.FileSystem.Watcher\src\System\IO\FileSystemWatcher.Win32.cs StartRaisingEvents方法内 这里通过 PreAllocatedOverlapped 官网解答 初始化 PreAllocatedOverlapped 类的新实例,并指定在每个异步 I/O 操作完成时调用的委托、可提供上下文的用户提供的对象以及充当缓冲区的托管对象。 使用时我在它监控目录下创建新文件就会触发 watcher.ReadDirectoryChangesCallback(errorCode, numBytes, state);这里 源码 AsyncReadState state.PreAllocatedOverlapped = new PreAllocatedOverlapped((errorCode, numBytes, overlappedPointer) => { AsyncReadState state = (AsyncReadState)ThreadPoolBoundHandle.GetNativeOverlappedState(overlappedPointer)!; state.ThreadPoolBinding.FreeNativeOverlapped(overlappedPointer); if (state.WeakWatcher.TryGetTarget( out FileSystemWatcher? watcher)) { watcher.ReadDirectoryChangesCallback(errorCode, numBytes, state); } }, state, buffer); |
2 F:\SourceCode\Net\Net8\runtime\src\libraries\System.IO.FileSystem.Watcher\src\System\IO\FileSystemWatcher.Win32.cs 这里是ReadDirectoryChangesCallback/ParseEventBufferAndNotifyForEach方法下 switch (info.Action) { case Interop.Kernel32.FileAction.FILE_ACTION_ADDED: NotifyFileSystemEventArgs(WatcherChangeTypes.Created, fileName); break; case Interop.Kernel32.FileAction.FILE_ACTION_REMOVED: NotifyFileSystemEventArgs(WatcherChangeTypes.Deleted, fileName); break; case Interop.Kernel32.FileAction.FILE_ACTION_MODIFIED: NotifyFileSystemEventArgs(WatcherChangeTypes.Changed, fileName); break; default: Debug.Fail($"Unknown FileSystemEvent action type! Value: {info.Action}"); break; } private void NotifyFileSystemEventArgs(WatcherChangeTypes changeType, ReadOnlySpan<char> name) { FileSystemEventHandler? handler = GetHandler(changeType); 这里获取你最开始绑定的委托方法 if (handler != null && MatchPattern(name.IsEmpty ? _directory : name)) { InvokeOn(new FileSystemEventArgs(changeType, _directory, name.IsEmpty ? null : name.ToString()), handler);//后续就是执行你委托并传参 } }
3 F:\SourceCode\Net\Net8\runtime\src\libraries\System.IO.FileSystem.Watcher\src\System\IO\FileSystemWatcher.cs private void InvokeOn(FileSystemEventArgs e, FileSystemEventHandler? handler) { if (handler != null) { ISynchronizeInvoke? syncObj = SynchronizingObject; if (syncObj != null && syncObj.InvokeRequired) syncObj.BeginInvoke(handler, new object[] { this, e }); else handler(this, e); 执行委托 } } 到达我们前面绑定的方法内 private static void OnProcess(object source, FileSystemEventArgs e) { if (e.ChangeType == WatcherChangeTypes.Created) { OnCreated(source, e); } else if (e.ChangeType == WatcherChangeTypes.Changed) { OnChanged(source, e); } else if (e.ChangeType == WatcherChangeTypes.Deleted) { OnDeleted(source, e); } }
分类:
C#/NetCore / IO
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)