简体   繁体   中英

Use timer with fileSystemWatcher in C#

The scenario is that I have a root folder to monitor any new folder (that contains files) and set a timer to zip each of them individually. However, I can't tell if the file in the folder is the last file before calling the zip function, and therefore I want to reset a timer to that folder, whenever there is a new file created before zipping the folder.

I using FileSystemWatcher to monitor both root folder and its sub-folders.

  1. I'm not sure how to create another watcher to monitor the file creation, perhaps in the OnTimedEvent method.
  2. I don't know how to reset the timer once detect a file of that folder. What I think is also write the code in the OnTimedEvent to reset it.

Below is part of my attempted code and the source code can be found here . Any help will be highly appreciated.

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

Here you have a simple extension method to reset given timer.

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

To get a timer object from inside of event you need to cast sender to System.Timers.Timer() or just use timer in static context.

There's a very clever library called Reactive Extensions , originally written by Microsoft as "Rx" but now placed in a "System.Reactive" namespace. It allows you to write complex event-driven code very simply.

For example, in a scenario like the one you're describing, you could "react" to the FileSystemWatcher 's events and use a Reactive "Throttle", which means you would only get notified of an event after a period of time when that event had not occurred. You can also merge multiple different events together. Put these two features together, and subscribe your method to it.

If that sounds like a possible solution, you may like to take a look at 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 (this is not a duplicate of that question because you're asking about Timers, and I'm suggesting you might want to use Reactive Extensions).

我使用lambda表达式来解决这个问题,将计时器和观察者“绑定”在一起,这就是我发现的类似于这篇文章的内容

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM