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);
     }
 }
复制代码

 

posted @   孤海飞雁  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示