先注册绑定事件
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);
}
}