FileSystemWatcher的Error事件通常在内部缓冲区溢出、权限丢失、监控路径不可达或系统资源不足时触发。该事件表明监控已中断,需通过捕获异常、记录日志、重新初始化实例并结合延迟重试机制恢复。常见异常包括InternalBufferOverflowException、IOException和Win32Exception,可通过增大InternalBufferSize、精准设置Filter、缩小监控范围及去抖处理等手段预防。核心处理逻辑是禁用旧Watcher,释放资源,延迟后重建新实例以实现稳定恢复。

FileSystemWatcher
Error
FileSystemWatcher
处理
FileSystemWatcher
Error
一个典型的
Error
using System;
using System.IO;
using System.Threading;
public class FileMonitor
{
private FileSystemWatcher _watcher;
private string _pathToWatch;
private Timer _rearmTimer; // 用于延迟重置watcher
public FileMonitor(string path)
{
_pathToWatch = path;
InitializeWatcher();
}
private void InitializeWatcher()
{
try
{
// 确保旧的watcher被正确处理
if (_watcher != null)
{
_watcher.EnableRaisingEvents = false;
_watcher.Error -= OnError;
_watcher.Created -= OnCreated; // 假设有其他事件处理器
_watcher.Changed -= OnChanged;
_watcher.Deleted -= OnDeleted;
_watcher.Renamed -= OnRenamed;
_watcher.Dispose();
}
_watcher = new FileSystemWatcher(_pathToWatch);
_watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
_watcher.IncludeSubdirectories = true;
// 增加内部缓冲区大小,预防InternalBufferOverflowException
_watcher.InternalBufferSize = 65536; // 默认8192,可以适当调大
_watcher.Created += OnCreated;
_watcher.Changed += OnChanged;
_watcher.Deleted += OnDeleted;
_watcher.Renamed += OnRenamed;
_watcher.Error += OnError; // 订阅Error事件
_watcher.EnableRaisingEvents = true;
Console.WriteLine($"FileSystemWatcher已启动,监控路径: {_pathToWatch}");
}
catch (Exception ex)
{
Console.WriteLine($"初始化FileSystemWatcher失败: {ex.Message}");
// 启动一个定时器尝试重新初始化
StartRearmTimer();
}
}
private void OnError(object sender, ErrorEventArgs e)
{
Exception ex = e.GetException();
Console.WriteLine($"FileSystemWatcher发生错误: {ex.GetType().Name} - {ex.Message}");
// 停止当前的watcher,避免重复错误或资源占用
if (_watcher != null)
{
_watcher.EnableRaisingEvents = false;
}
// 诊断具体错误类型
if (ex is InternalBufferOverflowException)
{
Console.WriteLine("警告: 内部缓冲区溢出!事件发生速度过快,Watcher来不及处理。");
// 此时可能需要增加InternalBufferSize或优化事件处理逻辑
}
else if (ex is System.ComponentModel.Win32Exception win32Ex)
{
Console.WriteLine($"Win32错误码: {win32Ex.NativeErrorCode}");
// 根据错误码判断具体问题,如权限不足 (5), 路径不存在 (3) 等
}
else if (ex is IOException)
{
Console.WriteLine("I/O操作异常,可能是路径不可达或权限问题。");
}
// ... 其他可能的异常类型
// 尝试重新启动watcher
Console.WriteLine("尝试重新启动FileSystemWatcher...");
StartRearmTimer(); // 使用定时器延迟重置,避免在短时间内反复失败
}
private void StartRearmTimer()
{
// 销毁旧的定时器,避免重复启动
_rearmTimer?.Dispose();
// 5秒后尝试重新初始化Watcher
_rearmTimer = new Timer(state =>
{
Console.WriteLine("重新初始化FileSystemWatcher...");
InitializeWatcher();
_rearmTimer?.Dispose(); // 任务完成后销毁定时器
}, null, TimeSpan.FromSeconds(5), Timeout.InfiniteTimeSpan);
}
// 假设的其他事件处理方法
private void OnCreated(object sender, FileSystemEventArgs e) => Console.WriteLine($"创建: {e.FullPath}");
private void OnChanged(object sender, FileSystemEventArgs e) => Console.WriteLine($"改变: {e.FullPath}");
private void OnDeleted(object sender, FileSystemEventArgs e) => Console.WriteLine($"删除: {e.FullPath}");
private void OnRenamed(object sender, RenamedEventArgs e) => Console.WriteLine($"重命名: {e.OldFullPath} -> {e.FullPath}");
public void Stop()
{
if (_watcher != null)
{
_watcher.EnableRaisingEvents = false;
_watcher.Error -= OnError;
// 解除其他事件订阅
_watcher.Created -= OnCreated;
_watcher.Changed -= OnChanged;
_watcher.Deleted -= OnDeleted;
_watcher.Renamed -= OnRenamed;
_watcher.Dispose();
_watcher = null;
}
_rearmTimer?.Dispose();
Console.WriteLine("FileSystemWatcher已停止。");
}
}
// 示例用法
public class Program
{
public static void Main(string[] args)
{
string path = @"C:\Temp\MonitorTest"; // 替换为你要监控的实际路径
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
Console.WriteLine($"创建测试目录: {path}");
}
FileMonitor monitor = new FileMonitor(path);
Console.WriteLine("按任意键退出...");
Console.ReadKey();
monitor.Stop();
}
}这个方案的核心在于:当
Error
FileSystemWatcher
System.Threading.Timer
FileSystemWatcher
FileSystemWatcher
Error
最最常见的,也是最让人“猝不及防”的,是内部缓冲区溢出(InternalBufferOverflowException
FileSystemWatcher
Error
FileSystemWatcher
其次,权限问题也是一个大头。如果你的应用程序在运行过程中,突然失去了对被监控目录的访问权限(比如管理员撤销了权限,或者目录被移动到了一个需要更高权限的地方),
FileSystemWatcher
Error
IOException
System.ComponentModel.Win32Exception
还有一种情况是监控的路径本身出了问题。比如你监控的是一个网络共享文件夹,结果网络断了;或者监控的本地目录被删除了、被移动了。虽然
Deleted
Renamed
FileSystemWatcher
Error
Error
此外,一些系统资源耗尽的情况,虽然不常见,但也可能导致
Error
FileSystemWatcher
理解这些触发场景,能帮助我们更好地定位问题,而不是盲目地去重启
FileSystemWatcher
编写健壮的
FileSystemWatcher
Error
首先,详细的日志记录是基石。当
Error
e.GetException()
Win32Exception
NativeErrorCode
Watcher
然后是智能的恢复策略。仅仅把
EnableRaisingEvents
false
true
Error
FileSystemWatcher
Watcher
EnableRaisingEvents = false;
Dispose()
Watcher
FileSystemWatcher
EnableRaisingEvents = true;
为了避免在错误持续发生时陷入无限的“重启-失败-重启”循环,引入延迟和重试机制非常重要。你可以使用
System.Threading.Timer
Error
Watcher
区分异常类型也很有用。如果
GetException()
InternalBufferOverflowException
InternalBufferSize
IOException
Win32Exception
最后,别忘了线程安全。
FileSystemWatcher
Error
ThreadPool
Invoke
Dispatcher.Invoke
与其被动地处理
Error
首先,也是最直接的,是合理设置InternalBufferSize
65536
131072
FileSystemWatcher
其次,精准地使用NotifyFilter
Filter
FileSystemWatcher
Filter
NotifyFilter
LastWrite
FileName
Filter
.log
FileSystemWatcher
再来,避免监控过于宽泛的路径。如果你要监控整个C盘,那几乎是自找麻烦。文件系统每时每刻都在发生变化,
FileSystemWatcher
对事件进行去抖(Debouncing)或节流(Throttling),虽然这更多是针对事件处理逻辑,但它间接有助于预防
Error
FileSystemWatcher
Changed
Watcher
最后,确保被监控路径的稳定性。如果你的应用程序经常需要监控那些可能被移动、删除或权限频繁变动的目录,那么
Error
这些预防措施并非万无一失,但它们能显著降低
Error
Watcher
以上就是FileSystemWatcher的Error事件怎么处理?文件监控异常的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号