在 C# 中使用计时器在每个目录上重复方法调用

Repeating a method call on each direcotry with timer elasped in C#

概览:

我创建了两个 FileSystemWatcher 来检测子文件夹及其文件创建。我还对第二个观察者(文件观察者)使用 Timer,它在动态调用 zip 方法之前为每个文件夹中的任何一个创建的每个文件重新启动计时器。

我尝试对每个文件夹执行此过程,但它会立即压缩所有文件夹,无论是否有文件移动到这些文件夹中。

下面是我模拟计时器和压缩过程的部分代码...调用压缩方法时,我可能无法将压缩文件移动到根文件夹。

文件Watcher里面的Timer

namespace ZipperAndWatcher
{
    public class Archive
    {
        public void CreateZip(string path)
        {    
          // zip method code
        }

    }

    public class FileWatcher
    {
        private FileSystemWatcher _fsw;
        private Archive _zip;
        private string _path;
        private Timer _timer;

        public FileWatcher()
        {
            _fsw = new FileSystemWatcher();
            _zip = new Archive();

            _path = @"D:\Documents\output";
            _timer = new Timer();
        }

        public void StartWatching()
        {
            var rootWatcher = _fsw;
            rootWatcher.Path = _path;
            rootWatcher.Created += new FileSystemEventHandler(OnRootFolderCreated);
            rootWatcher.EnableRaisingEvents = true;
            rootWatcher.Filter = "*.*";
        }

        private void OnRootFolderCreated(object sender, FileSystemEventArgs e)
        {
            string watchedPath = e.FullPath; // watched path

            // create another watcher for file creation and send event to timer
            FileSystemWatcher subFolderWatcher = new FileSystemWatcher();
            subFolderWatcher.Path = watchedPath + @"\";

            // Timer setting
            var aTimer = _timer;
            aTimer.Interval = 20000;

            // Lambda == args => expression
            // send event to subFolderWatcher
            aTimer.Elapsed += new ElapsedEventHandler((subfolderSender, evt) => OnTimedEvent(subfolderSender, evt, subFolderWatcher));
            aTimer.AutoReset = false;
            aTimer.Enabled = true;

            // sub-folder sends event to timer (and wait timer to notify subfolder)
            subFolderWatcher.Created += new FileSystemEventHandler((s, evt) => subFolderWatcher_Created(s, evt, aTimer));
            subFolderWatcher.Filter = "*.*";
            subFolderWatcher.EnableRaisingEvents = true;
        }

        private void OnTimedEvent(object sender, ElapsedEventArgs evt, FileSystemWatcher subFolderWatcher)
        {
            subFolderWatcher.EnableRaisingEvents = false;

            // Explicit Casting
            Timer timer = sender as Timer;
            timer.Stop();
            timer.Dispose();

            // Once time elapsed, zip the folder here?
            Console.WriteLine($"time up. zip process at {evt.SignalTime}");               
            Archive zip = _zip;
            zip.CreateZip(subFolderWatcher.Path.Substring(0, subFolderWatcher.Path.LastIndexOf(@"\")));

            subFolderWatcher.Dispose();
        }

        private void subFolderWatcher_Created(object sender, FileSystemEventArgs evt, Timer aTimer)
        {
            // if new file created, stop the timer
            //  then restart the timer
            aTimer.AutoReset = false;
            aTimer.Stop();
            aTimer.Start();
            Console.WriteLine($"restart the timer as {evt.Name} created on {DateTime.Now.ToString()}");
        }
    }
}

您在上一条评论中写道:"what I want is to only zip the specific subdirectories, which has no more files being added after the time elapsed while other subdirectories might still have files adding in, and it is not ready to be zipped"

因此在您的计时器处理程序 (OnTimedEvent) 中,您需要将路径传递到准备好压缩到 CreateZip 的目录,而不是父目录,即更改

zip.CreateZip(subFolderWatcher.Path.Substring(0, subFolderWatcher.Path.LastIndexOf(@"\")));

zip.CreateZip(subFolderWatcher.Path);

然后在您的 CreateZip 方法中只压缩作为参数传递的目录,而不是像您现在所做的那样压缩所有子目录。