I am developing a file monitoring system. What I need is to record each change, collect them to buffer, and throttled emit.
In other words, when there is a change, the buffer start recording. And if there's no change in 200ms, then emit all the changes (either one by one or collection is OK). The Throttle
method does not meet my requirement, since it only return the last element in each group (the green and purple point in the following diagram).
I've coded following (using GroupByUntil
) as suggested in this answer by cwharris:
using var watcher = new FileSystemWatcher("some_path")
{
Filter = "*.*",
NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size,
IncludeSubdirectories = true,
EnableRaisingEvents = true,
};
var Files = Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
h => watcher.Created += h, h => watcher.Created -= h)
.Select(x => x.EventArgs.FullPath)
.GroupByUntil(x => true, g => g.Throttle(TimeSpan.FromMilliseconds(200)))
.SelectMany(x => x.ToArray());
using IDisposable handle = Files.Subscribe(x => Console.WriteLine(String.Join("\n", x)));
Is there any other way to implement this? e.g. Using Buffer
and bufferClosingSelector
?