【问题标题】:FileSystemWatcher OnError is not working from Windows serviceFileSystemWatcher OnError 在 Windows 服务中不起作用
【发布时间】:2013-02-12 18:05:34
【问题描述】:

我在 Windows 服务中有一个 FileSystemWatcher 对象。我将它写在一个控制台应用程序中,使用该应用程序作为我的组件的存根。

我的组件实例化 FileSystemWatcher 并设置为监视映射的驱动器。从测试存根控制台应用程序和可部署的 Windows 服务来看,这对我来说非常有用。

我也有与 log4net 连接的 onError 事件,记录了一个致命级别的错误:

public FileSystemWatcher CreateFileWatcher()
    {
        FileSystemWatcher watcher = new FileSystemWatcher();

        try
        {
            log.Info("Configuring DPIFileWatcher");
            watcher.Filter = "*.xml";
            log.Info("DPIFileWatcher Filter set to: *.xml");
            string watcherPath = ConfigurationManager.AppSettings["InoundPath"].ToString();
            watcher.Path = watcherPath;
            log.Info(String.Format("DPIFileWatcher Path set to: {0}", watcherPath)); 

            watcher.Created += new FileSystemEventHandler(DPIWatcher_FileCreated);
            watcher.Changed += new FileSystemEventHandler(DPIWatcher_FileChanged);
            watcher.Error += new ErrorEventHandler(DPIWatcher_Error);
            watcher.EnableRaisingEvents = true;

            log.Info("DPIFileWatcher Configuration Successful.");
        }
        catch(Exception e)
        {
            log.Fatal(String.Format("Failed to configure DPIFileWatcher: {0}", e.Message));
        }

        return watcher;
    }

这是我的错误事件:

    private void DPIWatcher_Error(object source, ErrorEventArgs e)
    {
        log.Fatal(String.Format("FileWatacher error: {0}", e.GetException().Message));
    }

如果我通过拔下网卡测试网络错误丢失,我会从控制台应用程序中收到以下日志错误:

FATAL   [  12] 2013-02-12 12:14:02,142 SMILLER-E6430 METHOD: DPIWatcher_Error     GenFileWatch.DPIFileWatcher- FileWatacher error: The specified network name is no longer available (C:\Development\GenFileWatch\GenFileWatch\DPIFileWatcher.cs: 447)

但是从 Windows 服务中运行时,此日志错误将不起作用。

有人知道为什么或如何解决吗?

【问题讨论】:

  • 您是否从 OnStart 创建 FileSystemWatcher 实例?创建参考后如何处理它?它可能会过早收集,因此该事件永远不会触发。不过只是猜测。

标签: .net windows-services filesystemwatcher


【解决方案1】:

首先,您的服务是否使用有权访问您尝试监控的目录的帐户运行。 99% 的时间,运行“控制台”应用程序和运行“服务”在两个不同的用户上下文中运行。如果该用户上下文无权访问该目录(或 URL 仅表示另一个用户上下文中的某些内容),我认为不会调用 OnError。

其次,FileSystemWatcher 相当不可靠。它在大多数情况下都有效,但有时无效。它使用底层的原生函数 `` 记录在

当您第一次调用 ReadDirectoryChangesW 时,系统会分配一个 缓冲区来存储更改信息。此缓冲区与 目录句柄,直到它被关闭并且它的大小没有改变 在其生命周期内。调用之间发生的目录更改 这个函数被添加到缓冲区中,然后与下一个一起返回 称呼。如果缓冲区溢出,则缓冲区的全部内容为 丢弃,lpBytesReturned 参数包含零,并且 ReadDirectoryChangesW 函数失败并显示错误代码 ERROR_NOTIFY_ENUM_DIR

【讨论】:

  • 感谢您的反馈。不过,在您的第一条评论中,我们显然可以通过 Windows 服务访问文件共享,因为主要功能在该服务中运行良好。文件服务器在映射驱动器上的文件夹中侦听新文件,并触发 created 事件,我们在那里做我们想做的事情。因此 Win 服务可以访问该驱动器。所以我们无法弄清楚为什么 onerror 不会像控制台应用程序那样从 win 服务告诉我们“指定的网络名称不再可用”。
  • 另外,在您的第二条评论中,我们刚刚开始对此进行测试,但我读到您可以增加缓冲区大小来纠正此问题。虽然太多对性能不利。所以要做到恰到好处需要反复试验。
猜你喜欢
  • 1970-01-01
  • 2019-03-20
  • 2020-03-04
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多