C# FileSystemWatcher 未在服务中正确触发

C# FileSystemWatcher not triggering correctly in Service

我正在开发一项服务,在我的 OnStart 方法中,我有以下几行代码来设置我的 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 来执行此操作,还是应该使用其他代码,因为此代码在服务中?

根据您在那里所说的,可能有几件事。

首先要注意的是 var watcher 的声明看起来不是 class 变量,当它退出 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;

Common file system operations might raise more than one event. For example, when a file is moved from one directory to another, several OnChanged and some OnCreated and OnDeleted events might be raised. Moving a file is a complex operation that consists of multiple simple operations, therefore raising multiple events. Likewise, some applications (for example, antivirus software) might cause additional file system events that are detected by FileSystemWatcher

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

如果您要查找文件夹中出现的新文件,您应该使用:

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

Gist demonstrating it firing twice using Changed on LastWrite and a for predictable behaviour, a Gist demonstrating single fire on file create using Created and NotifyFilter.FileName

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