_lastChange = DateTime.MinValue;\r
_checker = new Timer(delegate(object state)\r
{\r
- _synchronizingObject.BeginInvoke((ThreadStart)delegate()\r
- {\r
- if (Changed != null)\r
- {\r
- /* debounce file watch changes: if last write time hadn't actually changed, don't bother notifying */\r
- DateTime thisChange = File.GetLastWriteTimeUtc(_watched);\r
- if (_lastChange != thisChange)\r
- {\r
- /* if any registered delegate didn't cancel the event, ask checker to check it again after a while */\r
- CancelEventArgs eventArgs = new CancelEventArgs(true);\r
- Changed(this, eventArgs);\r
- if (eventArgs.Cancel)\r
- _lastChange = thisChange;\r
- else\r
- _checker.Change(RECHECK_DELAY, Timeout.Infinite);\r
- }\r
- }\r
- },\r
- new object[0]);\r
+ CheckPath();\r
});\r
\r
_watcher = new FileSystemWatcher(Path.GetDirectoryName(watched), Path.GetFileName(watched));\r
_watcher.Changed += delegate(object sender, FileSystemEventArgs eventArgs)\r
{\r
/* check now */\r
- _checker.Change(0, Timeout.Infinite);\r
+ CheckPath();\r
};\r
_watcher.Created += delegate(object sender, FileSystemEventArgs eventArgs)\r
{\r
/* check now */\r
- _checker.Change(0, Timeout.Infinite);\r
+ CheckPath();\r
};\r
_watcher.Renamed += delegate(object sender, RenamedEventArgs eventArgs)\r
{\r
/* if file got changed to our name, check now */\r
if (eventArgs.Name == _watcher.Filter)\r
- _checker.Change(0, Timeout.Infinite);\r
+ CheckPath();\r
};\r
}\r
\r
_checker.Dispose();\r
}\r
\r
+ private void CheckPath()\r
+ {\r
+ /* schedule a check for the path on the synchronizing object, usually a window */\r
+ _synchronizingObject.BeginInvoke((ThreadStart)delegate()\r
+ {\r
+ if (Changed != null)\r
+ {\r
+ /* debounce file watch changes: if last write time hadn't actually changed, don't bother notifying */\r
+ /* NOTE: we only mutate _lastChange via this synchronized code, so there should be no race condition */\r
+ DateTime thisChange = File.GetLastWriteTimeUtc(_watched);\r
+ if (_lastChange != thisChange)\r
+ {\r
+ /* if any registered delegate didn't cancel the event, ask checker to check it again after a while */\r
+ CancelEventArgs eventArgs = new CancelEventArgs(true);\r
+ Changed(this, eventArgs);\r
+ if (eventArgs.Cancel)\r
+ _lastChange = thisChange;\r
+ else\r
+ _checker.Change(RECHECK_DELAY, Timeout.Infinite);\r
+ }\r
+ }\r
+ }, new object[0]);\r
+ \r
+ }\r
private const int RECHECK_DELAY = 100;\r
\r
private readonly string _watched;\r