运行 作为 Release 时,FileSystemWatcher 无法从两个目录获取事件

FileSystemWatcher can't get events from two directories when run as Release

如果作为发布运行,则仅从第一个目录发生事件。不管哪个是第一个。在调试模式下工作正常。

public class Program
{
    private static void Main(string[] args)
    {
        string[] paths = File.ReadAllLines("config.txt");
        List<FolderWatch> lw = new List<FolderWatch>();
        foreach (string path in paths)
            if (Path.IsPathFullyQualified(path))
                lw.Add(new FolderWatch(path));
        Thread.Sleep(Timeout.InfiniteTimeSpan);
    }
}
public class FolderWatch
{
    private FileSystemWatcher watcher;
    public FolderWatch(string path)
    {
        watcher = new FileSystemWatcher();
        watcher.Path = path;
        watcher.Created += OnCreated;
        watcher.EnableRaisingEvents = true;            
    }
    private static void OnCreated(object source, FileSystemEventArgs e)
    {
            try
            {
                File.AppendAllText("log.txt", "Event occured");
            }
            catch { }
    }
}

更新: 关于 watcher.

的范围,我做了一些更改
string[] paths = File.ReadAllLines(configpath);

FileSystemWatcher[] w_arr = new FileSystemWatcher[paths.Length];

这个有效:

w_arr[0] = new FileSystemWatcher();
if (Path.IsPathFullyQualified(paths[0]))
    SetupWatcher(w_arr[0], paths[0]);

w_arr[1] = new FileSystemWatcher();
if (Path.IsPathFullyQualified(paths[1]))
    SetupWatcher(w_arr[1], paths[1]);

在一个循环中它不起作用。仅发生第一个目录中的事件。

for (int i = 0; i < paths.Length; i++)
{
    if (Path.IsPathFullyQualified(paths[i]))
    {
        w_arr[i] = new FileSystemWatcher();
        SetupWatcher(w_arr[i], paths[i]);
    }
}

最后线程休眠并等待事件。

Thread.Sleep(Timeout.InfiniteTimeSpan);

private static void SetupWatcher(FileSystemWatcher watcher, string path)
{
    watcher.Path = path;
    watcher.EnableRaisingEvents = true;
    watcher.Filter = "*.pdf";
    watcher.Created += OnCreated;
    watcher.Error += OnError;
    GC.KeepAlive(watcher);
}

要确保 FileSystemWatcher 不会在程序结束前被垃圾回收,您可以这样做:

public class FolderWatch
{
    private FileSystemWatcher watcher;

    //...

    public void KeepAlive() => GC.KeepAlive(watcher);
}

...并在 Main 方法的 end 处为所有 FolderWatch 调用 KeepAlive

private static void Main(string[] args)
{
    var lw = new List<FolderWatch>();
    //...
    Thread.Sleep(Timeout.InfiniteTimeSpan);
    lw.ForEach(w => w.KeepAlive());
}