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

时间:2018-11-17 05:35:44

标签: c# timer filesystems zip filesystemwatcher

概述:

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

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

下面是我用来模拟计时器和zip过程的代码的一部分...在调用zip方法时,将zip文件移动到根文件夹时可能会遇到问题。

文件监视程序中的计时器

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()}");
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您在最后一条评论中写道:“我只想压缩特定的子目录,在经过一段时间后,不再添加任何文件,而其他子目录可能仍在添加文件,并且尚不准备压缩”

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

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

zip.CreateZip(subFolderWatcher.Path);

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