3

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??
    }
Stu_Dent
  • 370
  • 1
  • 4
  • 19
  • 1
    Why exactly are you using timers here? – X39 Oct 31 '18 at 13:56
  • Wanna try create a zip at a given time. – Stu_Dent Oct 31 '18 at 14:00
  • 2
    What are you trying to do here? Wait for file creation/modification to stop before processing the files? Avoid `file locked` exceptions for files that are still being written to? In both cases you'll need to track both the Created and Changed events. A single timer may not be enough. – Panagiotis Kanavos Oct 31 '18 at 14:03
  • @Patty_Putty I repeat: why are you using timerst here? You can zip any time, any thing, any where (as long as permissions are available)... so why you use that single timer? – X39 Oct 31 '18 at 15:23
  • I try to simulate a machine to monitor every new file creation in the subfolder. The problem is I can't tell if the number of the files and it sizes non wait for them finished before zipping it. This is why I need to set a timer to watch it. – Stu_Dent Nov 01 '18 at 03:24

3 Answers3

1

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.

Sebastian 506563
  • 6,980
  • 3
  • 31
  • 56
1

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).

Richardissimo
  • 5,596
  • 2
  • 18
  • 36
0

I sort of using the lambda expression to solve this issue as "binding" the timer and watcher together and this is what I found similar to this post.

Stu_Dent
  • 370
  • 1
  • 4
  • 19