Используйте таймер с fileSystemWatcher в C # - PullRequest
0 голосов
/ 31 октября 2018

Сценарий заключается в том, что у меня есть корневая папка для наблюдения за любой новой папкой (которая содержит файлы) и я настроил таймер для архивирования каждой из них по отдельности. Тем не менее, я не могу сказать, является ли файл в папке последним файлом перед вызовом функции zip, и поэтому я хочу сбросить таймер для этой папки всякий раз, когда перед созданием архива создается новый файл.

Я использую FileSystemWatcher для мониторинга как корневой папки, так и ее подпапок.

  1. Я не уверен, как создать еще один наблюдатель для наблюдения за созданием файла, возможно, в методе OnTimedEvent.
  2. Я не знаю, как сбросить таймер после обнаружения файла в этой папке. Я думаю также написать код в OnTimedEvent, чтобы сбросить его.

Ниже приведена часть моего попытанного кода, а исходный код можно найти здесь . Любая помощь будет высоко оценена.

    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??
    }

Ответы [ 3 ]

0 голосов
/ 03 ноября 2018

Существует очень умная библиотека с именем Reactive Extensions , изначально написанная Microsoft как «Rx», но теперь помещенная в пространство имен «System.Reactive». Это позволяет очень просто писать сложный управляемый событиями код.

Например, в сценарии, подобном тому, который вы описываете, вы можете «реагировать» на события FileSystemWatcher и использовать реактивный «газ», что означает, что вы будете получать уведомление о событии только после период времени, когда это событие не произошло. Вы также можете объединить несколько разных событий вместе. Соедините эти две функции и подпишите свой метод.

Если это звучит как возможное решение, вы можете взглянуть на Intro to Rx , и вот вопрос, касающийся этого подхода к решению этой проблемы, включая около 4 способов сделать это в различных ответах: Оберните средство просмотра файлов в реактивные расширения (это не дубликат этого вопроса, потому что вы спрашиваете о таймерах, и я полагаю, что вы, возможно, захотите использовать Reactive Extensions).

0 голосов
/ 11 ноября 2018

Я использую лямбда-выражение для решения этой проблемы как «связывание» таймера и наблюдателя, и это то, что я нашел похожим на этот пост .

0 голосов
/ 31 октября 2018

Здесь у вас есть простой метод расширения для сброса заданного таймера.

  public static void Reset(this Timer timer)
    {
      timer.Stop();
      timer.Start();
    }

Чтобы получить объект таймера изнутри события, вам нужно привести sender к System.Timers.Timer() или просто использовать таймер в статическом контексте.

...