在 C# 中将计时器与 fileSystemWatcher 一起使用
Use timer with fileSystemWatcher in C#
场景是我有一个根文件夹来监视任何新文件夹(包含文件)并设置一个计时器来单独压缩每个文件夹。但是,在调用 zip 函数之前,我无法判断文件夹中的文件是否是最后一个文件,因此我想在压缩文件夹之前创建新文件时将计时器重置为该文件夹。
我使用 FileSystemWatcher
来监控根文件夹及其子文件夹。
- 我不确定如何创建另一个观察器来监视文件创建,也许是在 OnTimedEvent 方法中。
- 一旦检测到该文件夹的文件,我不知道如何重置计时器。我的想法也是在OnTimedEvent中写代码来重置它。
下面是我尝试的部分代码,源代码可以找到here。任何帮助将不胜感激。
public class FileWatcher
{
private FileSystemWatcher _watcherRoot;
private Timer _timer;
private readonly string _watchedPath;
public FileWatcher(string path)
{
// _watcher = new FileSystemWatcher();
_timer = new Timer();
_watchedPath = path;
InitWatcher();
}
public void InitWatcher()
{
_watcherRoot = new FileSystemWatcher();
_watcherRoot.Path = _watchedPath;
_watcherRoot.IncludeSubdirectories = true;
_watcherRoot.EnableRaisingEvents = true;
_watcherRoot.Created += new FileSystemEventHandler(OnCreated);
}
private void OnCreated(object sender, FileSystemEventArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Created)
{
string fullPath = e.FullPath;
if (sender == _watcherRoot)
{
// If detect new folder, set the timer to 5 sec
_timer.Interval = 5000;
_timer.Elapsed += OnTimedEvent;
_timer.AutoReset = true;
_timer.Enabled = true;
// a directory
Console.WriteLine($"{fullPath.ToString()} created on {DateTime.Now}");
}
}
}
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
// Create a 2nd Watcher??
// Reset the timer in here??
}
这里有一个简单的扩展方法来重置给定的计时器。
public static void Reset(this Timer timer)
{
timer.Stop();
timer.Start();
}
要从事件内部获取计时器对象,您需要将 sender
转换为 System.Timers.Timer()
或仅在静态上下文中使用计时器。
有一个名为 Reactive Extensions 的非常聪明的库,最初由 Microsoft 编写为 "Rx" 但现在位于 "System.Reactive" 命名空间中。它可以让您非常简单地编写复杂的事件驱动代码。
例如,在您描述的场景中,您可以 "react" 到 FileSystemWatcher
的事件并使用 Reactive "Throttle",这意味着您将仅在该事件未发生的一段时间后才收到该事件的通知。您还可以将多个不同的事件合并在一起。将这两个功能放在一起,并订阅您的方法。
如果这听起来像是一个可能的解决方案,您可能想看看 Intro to Rx, and here is a question relating to that approach to solving this problem, including about 4 ways of doing this in the various answers: Wrap a file watcher in reactive extensions(这不是该问题的重复,因为您询问的是计时器,我建议您可以想使用 Reactive Extensions)。
我使用 lambda 表达式来解决这个问题,因为 "binding" 计时器和观察器一起使用,这就是我发现的与此类似的 post。
场景是我有一个根文件夹来监视任何新文件夹(包含文件)并设置一个计时器来单独压缩每个文件夹。但是,在调用 zip 函数之前,我无法判断文件夹中的文件是否是最后一个文件,因此我想在压缩文件夹之前创建新文件时将计时器重置为该文件夹。
我使用 FileSystemWatcher
来监控根文件夹及其子文件夹。
- 我不确定如何创建另一个观察器来监视文件创建,也许是在 OnTimedEvent 方法中。
- 一旦检测到该文件夹的文件,我不知道如何重置计时器。我的想法也是在OnTimedEvent中写代码来重置它。
下面是我尝试的部分代码,源代码可以找到here。任何帮助将不胜感激。
public class FileWatcher
{
private FileSystemWatcher _watcherRoot;
private Timer _timer;
private readonly string _watchedPath;
public FileWatcher(string path)
{
// _watcher = new FileSystemWatcher();
_timer = new Timer();
_watchedPath = path;
InitWatcher();
}
public void InitWatcher()
{
_watcherRoot = new FileSystemWatcher();
_watcherRoot.Path = _watchedPath;
_watcherRoot.IncludeSubdirectories = true;
_watcherRoot.EnableRaisingEvents = true;
_watcherRoot.Created += new FileSystemEventHandler(OnCreated);
}
private void OnCreated(object sender, FileSystemEventArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Created)
{
string fullPath = e.FullPath;
if (sender == _watcherRoot)
{
// If detect new folder, set the timer to 5 sec
_timer.Interval = 5000;
_timer.Elapsed += OnTimedEvent;
_timer.AutoReset = true;
_timer.Enabled = true;
// a directory
Console.WriteLine($"{fullPath.ToString()} created on {DateTime.Now}");
}
}
}
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
// Create a 2nd Watcher??
// Reset the timer in here??
}
这里有一个简单的扩展方法来重置给定的计时器。
public static void Reset(this Timer timer)
{
timer.Stop();
timer.Start();
}
要从事件内部获取计时器对象,您需要将 sender
转换为 System.Timers.Timer()
或仅在静态上下文中使用计时器。
有一个名为 Reactive Extensions 的非常聪明的库,最初由 Microsoft 编写为 "Rx" 但现在位于 "System.Reactive" 命名空间中。它可以让您非常简单地编写复杂的事件驱动代码。
例如,在您描述的场景中,您可以 "react" 到 FileSystemWatcher
的事件并使用 Reactive "Throttle",这意味着您将仅在该事件未发生的一段时间后才收到该事件的通知。您还可以将多个不同的事件合并在一起。将这两个功能放在一起,并订阅您的方法。
如果这听起来像是一个可能的解决方案,您可能想看看 Intro to Rx, and here is a question relating to that approach to solving this problem, including about 4 ways of doing this in the various answers: Wrap a file watcher in reactive extensions(这不是该问题的重复,因为您询问的是计时器,我建议您可以想使用 Reactive Extensions)。
我使用 lambda 表达式来解决这个问题,因为 "binding" 计时器和观察器一起使用,这就是我发现的与此类似的 post。