FileSystemWatcher, Rx and Throttle

Imagine that we want to be notified if a directory files changed.

In general, when we use files, we don’t need to have a real time application.

Moreover, if we change many files in same time, we perhaps don’t need to have many notification and one notification at the end could be enough.

 

For this case, Rx and particularly Throttle method is very useful.

In our case, I create a FileChangedEvent which can contain notification information we may need.

public class FileChangedEvent

{

}

 

Then, I create a class FileWatcher that returns an IObservable<FileChangedEvent>.

This class need the directory path, the type of files to watch and the minimum time between two changes before having a notifications.

public class FileWatcher

{

    public FileWatcher(string path, string filter, TimeSpan throttle)

    {

        Path = path;

        Filter = filter;

        Throttle = throttle;

    }

 

    public string Path { get; private set; }

    public string Filter { get; private set; }

    public TimeSpan Throttle { get; private set; }

 

    public IObservable<FileChangedEvent> GetObservable()

    {

        return Observable.Create<FileChangedEvent>(observer =>

            {

                FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Path, Filter) { EnableRaisingEvents = true };

                FileSystemEventHandler created = (_, __) => observer.OnNext(new FileChangedEvent());

                FileSystemEventHandler changed = (_, __) => observer.OnNext(new FileChangedEvent());

                RenamedEventHandler renamed = (_, __) => observer.OnNext(new FileChangedEvent());

                FileSystemEventHandler deleted = (_, __) => observer.OnNext(new FileChangedEvent());

                ErrorEventHandler error = (_, errorArg) => observer.OnError(errorArg.GetException());

                fileSystemWatcher.Created += created;

                fileSystemWatcher.Changed += changed;

                fileSystemWatcher.Renamed += renamed;

                fileSystemWatcher.Deleted += deleted;

                fileSystemWatcher.Error += error;

                return () =>

                    {

                        fileSystemWatcher.Created -= created;

                        fileSystemWatcher.Changed -= changed;

                        fileSystemWatcher.Renamed -= renamed;

                        fileSystemWatcher.Deleted -= deleted;

                        fileSystemWatcher.Error -= error;

                        fileSystemWatcher.Dispose();

                    };

            }).Throttle(Throttle);

    }

}

 

Now we can use the observable like this:

var fileWatcher = new FileWatcher(".", "*.*", TimeSpan.FromSeconds(5));
var fileObserver = fileWatcher.GetObservable().Subscribe(fce => { /*TODO*/ });

Imagine that if we have n changes on the directory in less than 5 seconds between two consecutive changes.
With this code, we have one only notification, 5 seconds after the last one.

This entry was posted in 17207, 7671. Bookmark the permalink.

One Response to FileSystemWatcher, Rx and Throttle

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>