You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FileSystemWatcher Created事件未触发问题排查求助

问题分析与解决方案

你的怀疑完全正确——FileSystemWatcher监听共享目录时,一旦发生网络中断导致SMB连接丢失,它不会自动恢复连接,必须重新初始化才能继续触发事件。

为什么会出现这个问题?

Windows的FileSystemWatcher在监听远程共享目录时,依赖底层SMB协议维持和远程服务器的连接。当网络中断后,这个连接会被直接断开,而FileSystemWatcher本身没有内置的重连逻辑,会一直处于“失效”状态,无法再接收远程目录的变更通知。

而你提到的那个近期启动的服务实例能正常工作,正是因为它是在网络恢复后初始化的,成功建立了新的SMB连接,所以可以正常触发事件。

排查与解决方法

1. 验证网络中断导致的连接丢失

你可以通过以下方式确认原因:

  • 查看Windows事件查看器(Event Viewer)的系统日志,搜索SMB相关事件(比如事件ID 50、1005等),检查是否有网络中断后共享连接断开的记录。
  • 在服务中添加状态日志,记录FileSystemWatcher的初始化状态,同时定期用Directory.Exists(filePath)检查共享目录是否可访问,当目录不可访问时标记状态,验证是否和网络中断时间吻合。

2. 实现自动重连机制

既然FileSystemWatcher不会自动恢复,我们需要手动添加重连逻辑,核心思路是:检测到共享连接失效时,销毁旧的FileSystemWatcher实例并重新初始化。

这里提供一个简单的实现示例:

首先,封装一个重新初始化的方法:

private void ReinitializeWatcher(string targetPath)
{
    // 先清理旧实例,避免资源泄漏
    if (_fileSystemWatcher != null)
    {
        _fileSystemWatcher.EnableRaisingEvents = false;
        _fileSystemWatcher.Created -= FileSystemWatcher_Created;
        _fileSystemWatcher.Dispose();
        _fileSystemWatcher = null;
    }

    // 尝试重新创建并初始化
    try
    {
        _fileSystemWatcher = new FileSystemWatcher(targetPath);
        _fileSystemWatcher.Created += FileSystemWatcher_Created;
        _fileSystemWatcher.IncludeSubdirectories = true;
        _fileSystemWatcher.EnableRaisingEvents = true;
        // 记录日志:Watcher重新初始化成功
    }
    catch (Exception ex)
    {
        // 记录日志:初始化失败(比如共享目录仍不可访问)
        // 可以设置重试逻辑,比如5分钟后再次尝试
    }
}

然后,添加两种触发重连的方式:

  • 定期检查共享目录状态:用Timer定时任务每隔一段时间检查共享目录是否可访问,不可访问时触发重连:
private readonly Timer _statusCheckTimer;

// 在服务初始化时启动定时器
_statusCheckTimer = new Timer(CheckDirectoryStatus, null, TimeSpan.Zero, TimeSpan.FromMinutes(5));

private void CheckDirectoryStatus(object state)
{
    if (!Directory.Exists(filePath))
    {
        // 共享目录不可达,触发重连
        ReinitializeWatcher(filePath);
    }
}
  • 监听网络状态变化:通过SystemEvents.NetworkAvailabilityChanged事件,在网络恢复时自动检查并重连:
SystemEvents.NetworkAvailabilityChanged += (sender, e) =>
{
    if (e.IsAvailable)
    {
        // 网络恢复,立即检查共享目录并尝试重连
        CheckDirectoryStatus(null);
    }
};

3. 其他需要注意的点

  • 确保服务运行的账号有足够权限访问共享目录(不过你重启后能正常触发,说明权限没问题)。
  • 如果共享目录文件变更频繁,可通过调整InternalBufferSize避免FileSystemWatcher缓冲区溢出,但这和你的问题场景不符,仅作为额外排查项。

内容的提问来源于stack exchange,提问作者Karan Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:43:29