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  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 @ 2024-04-09 19:27  孤海飞雁  阅读(54)  评论(0)    收藏  举报