/IO/FileSystemWatcher.cs |
@@ -0,0 +1,73 @@ |
using System; |
using System.IO; |
using System.Runtime.Caching; |
|
namespace wasSharpNET.IO |
{ |
/// <summary> |
/// Filesystem watcher that ensures events are not fired twice |
/// </summary> |
/// <remarks>derived from Ben Hall @ benhall.io</remarks> |
public class FileSystemWatcher : IDisposable |
{ |
public event FileSystemEventHandler FilesytemEvent; |
private readonly CacheItemPolicy _cacheItemPolicy; |
private readonly int _cacheTimeMilliseconds = 1000; |
private readonly MemoryCache _memCache; |
|
public FileSystemWatcher(string path, NotifyFilters notifyFilters, string filter) |
{ |
_memCache = MemoryCache.Default; |
|
var watcher = new System.IO.FileSystemWatcher |
{ |
Path = path, |
NotifyFilter = notifyFilters, |
Filter = filter |
}; |
|
_cacheItemPolicy = new CacheItemPolicy |
{ |
RemovedCallback = OnRemovedFromCache |
}; |
|
watcher.Changed += OnChanged; |
watcher.EnableRaisingEvents = true; |
} |
|
public FileSystemWatcher(string path, NotifyFilters notifyFilters, string filter, int timeout) : this(path, |
notifyFilters, filter) |
{ |
_cacheTimeMilliseconds = timeout; |
} |
|
// Add file event to cache for CacheTimeMilliseconds |
private void OnChanged(object source, FileSystemEventArgs e) |
{ |
_cacheItemPolicy.AbsoluteExpiration = |
DateTimeOffset.Now.AddMilliseconds(_cacheTimeMilliseconds); |
|
// Only add if it is not there already (swallow others) |
_memCache.AddOrGetExisting(e.Name, e, _cacheItemPolicy); |
} |
|
// Handle cache item expiring |
private void OnRemovedFromCache(CacheEntryRemovedArguments args) |
{ |
if (args.RemovedReason != CacheEntryRemovedReason.Expired) return; |
|
// Now actually handle file event. |
OnFileSystemEvent((FileSystemEventArgs)args.CacheItem.Value); |
} |
|
protected virtual void OnFileSystemEvent(FileSystemEventArgs e) |
{ |
FilesytemEvent?.Invoke(this, e); |
} |
|
public void Dispose() |
{ |
_memCache.Dispose(); |
} |
} |
} |