private void RemoveFolderRecordIfItIsEmpty(FolderContentsEnumerator folderContentsEnumerator, List <WeakReference <FolderContentsEnumerator> > allIteratorsForGivenFolder) { if (allIteratorsForGivenFolder.Count == 0) { _foldersToIterators.Remove(folderContentsEnumerator.FolderBeingEnumerated.Id); } }
public void InvalidateEnumeratorsForFolder(Guid folderId) { lock (_stateChangeCriticalSection) { if (_foldersToIterators.ContainsKey(folderId)) { List <WeakReference <FolderContentsEnumerator> > allIteratorsForGivenFolder = _foldersToIterators[folderId]; for (int i = 0; i < allIteratorsForGivenFolder.Count; i++) { WeakReference <FolderContentsEnumerator> enumeratorReference = allIteratorsForGivenFolder[i]; FolderContentsEnumerator enumerator = enumeratorReference.ReferencedObject; if (enumerator == null) //Note: по идее такого все же быть не должно - итератор нам просигналит о завершении своего существования в любом случае. { enumeratorReference.Dispose(); allIteratorsForGivenFolder.RemoveAt(i); i--; } else { enumerator.MarkAsInvalid(); // все: ходить по элементам больше не получится. } } if (allIteratorsForGivenFolder.Count == 0) { _foldersToIterators.Remove(folderId); } } } }
/// <summary> /// Создает Iterator для перебора файлов в папке, имена которых удовлетворяют заданной маске (<paramref name="patternNamesOfFilesMustMatch"/>). /// Работает рекурсивно - то есть перебирает и файлы во всех подпапках указанной папки. /// Note: генерирует исключение (<see cref="InvalidOperationException"/>), если папка, по которой производится обход, меняется во время обхода (итераторы не thread-safe, я бы их лучше не показывал, но это явно зафиксированное требования). /// </summary> /// <param name="folderToEnumerateFilesIn">Папка, в которой следует искать файлы.</param> /// <param name="patternNamesOfFilesMustMatch">Маска для поиска файлов. Звездочка означает любую последовательность символов. Знак вопроса - один любой символ.</param> /// <returns>Iterator для перебора файлов в папке, имена которых удовлетворяют заданной маске (<paramref name="patternNamesOfFilesMustMatch"/>)</returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="FolderNotFoundException"></exception> /// <exception cref="ObjectDisposedException"></exception> public IEnumerator <FileInfo> EnumerateFilesUnderFolder(string folderToEnumerateFilesIn, string patternNamesOfFilesMustMatch) { MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(folderToEnumerateFilesIn, "folderToEnumerateFilesIn"); MethodArgumentValidator.ThrowIfStringIsNullOrEmpty(patternNamesOfFilesMustMatch, "patternNamesOfFilesMustMatch"); Monitor.Enter(_operationExecutionCriticalSection); try { ThrowIfDisposed(); var nodeResolvingResult = _nodeResolver.ResolveFolderNodeByPath(folderToEnumerateFilesIn); var folder = new FolderInfo(nodeResolvingResult.ResolvedNode, folderToEnumerateFilesIn); var enumerator = new FolderContentsEnumerator(folder, patternNamesOfFilesMustMatch, _folderEnumeratorRegistry, this); _folderEnumeratorRegistry.RegisterEnumerator(enumerator); return(enumerator); } catch (InvalidPathException) { throw new FolderNotFoundException( "Не удалось найти папку по указанному пути (\"{0}\")".FormatWith(folderToEnumerateFilesIn)); } finally { Monitor.Exit(_operationExecutionCriticalSection); } }
public void Unregister(FolderContentsEnumerator folderContentsEnumerator) { if (folderContentsEnumerator == null) { throw new ArgumentNullException("folderContentsEnumerator"); } Monitor.Enter(_stateChangeCriticalSection); try { List <WeakReference <FolderContentsEnumerator> > allIteratorsForGivenFolder = _foldersToIterators[folderContentsEnumerator.FolderBeingEnumerated.Id]; for (int i = 0; i < allIteratorsForGivenFolder.Count; i++) { WeakReference <FolderContentsEnumerator> enumeratorReference = allIteratorsForGivenFolder[i]; FolderContentsEnumerator enumerator = enumeratorReference.ReferencedObject; if (Object.ReferenceEquals(enumerator, folderContentsEnumerator)) { enumeratorReference.Dispose(); allIteratorsForGivenFolder.RemoveAt(i); i--; } } RemoveFolderRecordIfItIsEmpty(folderContentsEnumerator, allIteratorsForGivenFolder); } catch (KeyNotFoundException) { } finally { Monitor.Exit(_stateChangeCriticalSection); } }
public void RegisterEnumerator(FolderContentsEnumerator folderContentsEnumerator) { if (folderContentsEnumerator == null) { throw new ArgumentNullException("folderContentsEnumerator"); } lock (_stateChangeCriticalSection) { List <WeakReference <FolderContentsEnumerator> > allIteratorsForGivenFolder; if (_foldersToIterators.ContainsKey(folderContentsEnumerator.FolderBeingEnumerated.Id)) { allIteratorsForGivenFolder = _foldersToIterators[folderContentsEnumerator.FolderBeingEnumerated.Id]; } else { allIteratorsForGivenFolder = new List <WeakReference <FolderContentsEnumerator> >(); _foldersToIterators[folderContentsEnumerator.FolderBeingEnumerated.Id] = allIteratorsForGivenFolder; } allIteratorsForGivenFolder.Add(new WeakReference <FolderContentsEnumerator>(folderContentsEnumerator)); } }