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);
                    }
                }
            }
        }
Exemplo n.º 3
0
        /// <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));
            }
        }