【问题标题】:C# FileSystemWatcher not triggering correctly in ServiceC# FileSystemWatcher 在服务中未正确触发
【发布时间】:2017-11-01 16:43:23
【问题描述】:

我正在开发一项服务,在我的OnStartmethod 中,我有以下代码行来设置我的FileSystemWatcher

Log.Info($"File location {_location}");
var watcher = new FileSystemWatcher(_location);      
watcher.Changed += new FileSystemEventHandler(OnChanged);

然后在我的OnChanged 方法中,我想像这样启动一个计时器:

private void OnChanged(object source, FileSystemEventArgs e)
{
    Log.Info($"A file has been placed in {_location} starting timer");
    OnTimer(null, null); //run immediately at startup
    StartEventTimer();
}

计时器代码有效,所以我知道这不是问题,同样在我的日志中我知道它正在检查正确的位置。我错过了什么?

我想要我的代码做的就是触发我的计时器,当文件被放置在我的目标位置但我无法这样做时。我应该使用FileSystemWatcher来执行此操作是否正确,或者我应该使用其他东西,因为此代码在服务中?

【问题讨论】:

    标签: c# service filesystemwatcher


    【解决方案1】:

    您可能会发现 Changed 事件在新文件上多次触发,这是某些应用程序的常见问题,这可能会在以后产生不必要的副作用。看看并尝试改为创建。

    如果您正在寻找出现在文件夹中的新文件,您应该使用:

    watcher.NotifyFilter = NotifyFilters.FileName;
    watcher.Created += OnCreated;
    

    Gist demonstrating it firing twice using Changed on LastWrite 和用于可预测行为的 Gist demonstrating single fire on file create using Created and NotifyFilter.FileName

    只需在控制台应用程序中运行它并将文件复制到 c:\temp。

    【讨论】:

    • 为了记录,我没有投反对票,但我有兴趣看到关于重复解雇的解释。除非文件被创建/更改两次,否则给出的代码示例看起来不会触发两次
    • 多个事件是一些地方提到的已知问题,例如MSDN FileSystemWatcher class page 的底部。我必须对刚刚完成的一些工作进行广泛的试验,以处理文件夹中的新文件。运行时的 Gists 以及复制到文件夹中的文件将演示这种情况。这与操作系统和某些应用程序的行为方式有关。我们最终通过 MemoryCache 缓冲事件,作为一种安全网,但到目前为止,使用 NotifyFilters.FileName 创建已被证明是可靠的。
    • 很高兴知道!不过,您可能希望在答案中包含该详细信息。我怀疑这就是您投反对票的原因,因为“引发了多个事件,请尝试此代码”,没有后续解释或详细信息 - 所以在细节上蓬勃发展 :) 我会投赞成票,因为信息是准确的直到你提出来,我自己才意识到这一点
    【解决方案2】:

    根据您在此处所说的内容,可能有几件事。

    首先要注意的是var watcher 的声明看起来不是一个类变量,当它退出OnStart() 时会超出范围。您需要将声明移到此之外。

    感兴趣的第二项是看起来EnableRaisingEvents 没有被设置。下面是FileSystemWatcher 的工作示例。

    public class SomeService
    {
        private FileSystemWatcher _watcher;
        public void OnStart()
        {
            // set up the watcher
            _watcher = new FileSystemWatcher(_location);
            _watcher.Path = path;
            _watcher.NotifyFilter = NotifyFilters.LastWrite;
            _watcher.Filter = "*.*";
            _watcher.Changed += new FileSystemEventHandler(OnChanged);
            _watcher.EnableRaisingEvents = true;
        }
    }
    

    编辑

    正如 Ben Hall 提到的,当一个文件被移动到文件夹中时,可能会为同一个文件引发多个事件。根据MSDN documentation;

    常见的文件系统操作可能引发多个事件。例如,当一个文件从一个目录移动到另一个目录时,可能会引发几个 OnChanged 以及一些 OnCreated 和 OnDeleted 事件。移动文件是一个复杂的操作,由多个简单的操作组成,因此会引发多个事件。同样,某些应用程序(例如,防病毒软件)可能会导致 FileSystemWatcher 检测到的其他文件系统事件

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多