如何在执行程序时无限期启动c# FileSystemWatcher函数?
How to start the c# FileSystemWatcher function indefinitely when executing the program?
我正在使用 .Net Framework 开发 windows 程序。
我想创建一个程序,当使用 FileSystemWatcher 在特定文件夹中创建文件时执行函数。
下面是我的代码。
public async Task<int> CollectFunc() {
string path = @"C:\test";
try
{
FileSystemWatcher watcher = new FileSystemWatcher
{
Path=path
Filter="test.log"
};
watcher.Created += new FileSystemEventHandler(WatcherFunc);
watcher.IncludeSubdrectories=true;
watcher.EnableRaisingEvents=true;
}
catch
{
Console.WriteLine("Error");
}
while(true)
{
await Task.Delay(100000);
}
}
public async void WatcherFunc(object source, FileSystemEventArgs e) {
Console.WriteLine("File Created: " + e.FullPath);
}
当我启动程序时,文件创建会受到监控,直到我关闭程序。
示例如下。
9 月 1 日,创建了以下文件。
C:\test200901\test.log
然后程序打印“文件已创建:C:\test200901\test.log”。
9 月 2 日
C:\test200902\test.log文件创建,
然后程序将输出“文件已创建:C:\test200902\test.log”。
...
但有时 Watcher 不工作,我必须重新启动程序。
如果有比我的源代码更好或更稳定的逻辑,请告诉我。
期待您的回复。
试试这些改变:
// Introduce a class field, to prevent the watcher reference from going out of scope.
private FileSystemWatcher watcher = null;
public void CollectFunc() { // no need for async any more ...
string path = @"C:\test";
try
{
// Init class field
watcher = new FileSystemWatcher
{
Path=path
Filter="test.log"
};
watcher.Created += new FileSystemEventHandler(WatcherFunc);
watcher.IncludeSubdrectories=true;
watcher.EnableRaisingEvents=true;
}
catch (Exception ex)
{
// Better know what the problem actually was.
Console.WriteLine($"Error: {ex.Message}");
}
// It's a winforms app - we don't need to block this => away with while(true)
}
public async void WatcherFunc(object source, FileSystemEventArgs e)
{
// Just in case, catch and log exceptions
try{
Console.WriteLine("File Created: " + e.FullPath);
} catch( Exception ex ) {
// TODO: Log Exception or handle it.
}
}
最重要的是:这是一个已知问题,大量和频繁的更改会导致观察程序中的某些缓冲区溢出(如果仍然适用,但我记得 运行 到此几年前)。
注册一个处理程序到 Error
事件可能也是值得的:https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher.error?view=netcore-3.1
我猜你在事件处理程序中的 Console.WriteLine
只是一个示例代码,你实际上做的不止于此。过去,我发现如果我在这里保持代码非常小并尽快处理事件,它可以减轻 FileSystemWatcher 缓冲区的压力。
所以,我所做的是将文件路径放入队列中,并让该队列在不同的线程上处理。这可确保尽快处理事件,同时不会丢失任何事件。 Peeks 可以被越来越大的队列捕获,并由另一个线程独立处理。换句话说:事情堆积 在 观察者缓冲区之外。
我正在使用 .Net Framework 开发 windows 程序。
我想创建一个程序,当使用 FileSystemWatcher 在特定文件夹中创建文件时执行函数。
下面是我的代码。
public async Task<int> CollectFunc() {
string path = @"C:\test";
try
{
FileSystemWatcher watcher = new FileSystemWatcher
{
Path=path
Filter="test.log"
};
watcher.Created += new FileSystemEventHandler(WatcherFunc);
watcher.IncludeSubdrectories=true;
watcher.EnableRaisingEvents=true;
}
catch
{
Console.WriteLine("Error");
}
while(true)
{
await Task.Delay(100000);
}
}
public async void WatcherFunc(object source, FileSystemEventArgs e) {
Console.WriteLine("File Created: " + e.FullPath);
}
当我启动程序时,文件创建会受到监控,直到我关闭程序。
示例如下。
9 月 1 日,创建了以下文件。 C:\test200901\test.log 然后程序打印“文件已创建:C:\test200901\test.log”。
9 月 2 日 C:\test200902\test.log文件创建, 然后程序将输出“文件已创建:C:\test200902\test.log”。
...
但有时 Watcher 不工作,我必须重新启动程序。
如果有比我的源代码更好或更稳定的逻辑,请告诉我。
期待您的回复。
试试这些改变:
// Introduce a class field, to prevent the watcher reference from going out of scope.
private FileSystemWatcher watcher = null;
public void CollectFunc() { // no need for async any more ...
string path = @"C:\test";
try
{
// Init class field
watcher = new FileSystemWatcher
{
Path=path
Filter="test.log"
};
watcher.Created += new FileSystemEventHandler(WatcherFunc);
watcher.IncludeSubdrectories=true;
watcher.EnableRaisingEvents=true;
}
catch (Exception ex)
{
// Better know what the problem actually was.
Console.WriteLine($"Error: {ex.Message}");
}
// It's a winforms app - we don't need to block this => away with while(true)
}
public async void WatcherFunc(object source, FileSystemEventArgs e)
{
// Just in case, catch and log exceptions
try{
Console.WriteLine("File Created: " + e.FullPath);
} catch( Exception ex ) {
// TODO: Log Exception or handle it.
}
}
最重要的是:这是一个已知问题,大量和频繁的更改会导致观察程序中的某些缓冲区溢出(如果仍然适用,但我记得 运行 到此几年前)。
注册一个处理程序到 Error
事件可能也是值得的:https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher.error?view=netcore-3.1
我猜你在事件处理程序中的 Console.WriteLine
只是一个示例代码,你实际上做的不止于此。过去,我发现如果我在这里保持代码非常小并尽快处理事件,它可以减轻 FileSystemWatcher 缓冲区的压力。
所以,我所做的是将文件路径放入队列中,并让该队列在不同的线程上处理。这可确保尽快处理事件,同时不会丢失任何事件。 Peeks 可以被越来越大的队列捕获,并由另一个线程独立处理。换句话说:事情堆积 在 观察者缓冲区之外。