// Advances the enumerator to the next file to be processed and attempts to process it. private void EnumerateNextFile(string watchDirectory, DateTime enumerationStart, HashSet <string> enumeratedFiles, IEnumerator <string> enumerator) { // If the file processor has been // disposed, return immediately if (m_disposed) { return; } if (enumerator.MoveNext()) { // Add the file to the collection of enumerated files enumeratedFiles.Add(enumerator.Current); // Attempt to process this file if (File.Exists(enumerator.Current) && MatchesFilter(enumerator.Current)) { TouchLockAndProcess(enumerator.Current); } // Move to the next file m_processingQueue.Add(() => EnumerateNextFile(watchDirectory, enumerationStart, enumeratedFiles, enumerator)); } else { // No more files to process, so we use the enumeratedFiles hash set // to clean up files that have been removed from the watch directory Predicate <string> predicate = filePath => { DateTime lastWriteTime; bool enumerated = enumeratedFiles.Contains(filePath); bool touched = m_touchedFiles.TryGetValue(filePath, out lastWriteTime) && (lastWriteTime > enumerationStart); bool isInWatchPath = filePath.StartsWith(watchDirectory, StringComparison.OrdinalIgnoreCase); return(!enumerated && !touched && isInWatchPath); }; m_processedFiles.RemoveWhere(predicate); } }