运行 作为 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());
}
如果作为发布运行,则仅从第一个目录发生事件。不管哪个是第一个。在调试模式下工作正常。
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());
}