private async void Regroup(GroupingAttribute attribute, CancellationToken token) { GroupedFilesCollection rollbackGroupsBuffer = new GroupedFilesCollection(_progress); // Сохраним результаты предыдущей сортировки для восстановления в случае отката операции foreach (var group in _duplicatesCollection) { rollbackGroupsBuffer.Add(group); } // Разделим полученный ранее полный список дубликатов на группы по указанному атрибуту try { await _duplicatesCollection.RegroupDuplicates(attribute, token); } catch (OperationCanceledException) { _duplicatesCollection.Clear(); // Восстановим результаты предыдущей сортировки foreach (var group in rollbackGroupsBuffer) { _duplicatesCollection.Add(group); } OperationStatus status = new OperationStatus { Id = SearchStatus.GroupingCanceled }; ((IProgress <OperationStatus>)_progress).Report(status); } }
/// <summary> /// Поиск дубликатов файлов /// </summary> /// <returns></returns> private async void Search(ObservableCollection <GroupingAttribute> compareAttribsList, CancellationToken cancelToken) { OperationStatus status = new OperationStatus { Id = SearchStatus.NewFileSelected }; _filesCollection.Clear(); _duplicatesCollection.Clear(); try { // Отберём файлы из заданных пользователем каталогов для дальнейшего анализа в FilesCollection DateTime s = DateTime.Now; foreach (Folder folder in _foldersCollection) { await GetFolderFiles(folder, cancelToken, status); } TimeSpan duration = DateTime.Now - s; // 18000 файлов 777 sec // 2 331 file 7 sec //// Если нашлись файлы подходящие под условия фильтра то выполняем среди них поиск дубликатов if (_filesCollection.Count > 1) { _duplicatesCollection.Add(_filesCollection); await _duplicatesCollection.RemoveNonDuplicates(compareAttribsList, cancelToken); } if (PrimaryFolder != null) { // Дополнительно удалим из списка дубликатов файлы не дублирующие файлы из PrimaryFolder DeleteNonPrimaryFolderDuplicates(); } else { // Или перегруппируем файлы по атрибуту выбранному в ComboBox для группировки await _duplicatesCollection.RegroupDuplicates(_fileCompareOptions.SelectedGroupAttrib, cancelToken); } status.Id = SearchStatus.SearchCompleted; ((IProgress <OperationStatus>)_progress).Report(status); } catch (OperationCanceledException) { _filesCollection.Clear(); _duplicatesCollection.Clear(); if (status.Id != SearchStatus.Error) { status.Id = SearchStatus.SearchCanceled; } ((IProgress <OperationStatus>)_progress).Report(status); } }
public async Task RemoveNonDuplicates(ObservableCollection <GroupingAttribute> attributeList, CancellationToken cancelToken) { IProgress <OperationStatus> progress = m_progress; var status = new OperationStatus { Id = DataModel.SearchStatus.Comparing, TotalItems = this[0].Count, HandledItems = 0, Stage = string.Empty }; var localAttributeList = new List <GroupingAttribute>(attributeList); GroupingAttribute size = localAttributeList.FirstOrDefault <GroupingAttribute>(a => a.Attribute == FileAttribs.Size); GroupingAttribute content = localAttributeList.FirstOrDefault <GroupingAttribute>(a => a.Attribute == FileAttribs.Content); if (content != null && size == null) { localAttributeList.Add(new GroupingAttribute("Size", FileAttribs.Size, 0)); } var groupsBuffer = new GroupedFilesCollection(m_progress); IEnumerable <GroupingAttribute> query = from attribute in localAttributeList orderby attribute.Attribute ascending select attribute; foreach (var attribute in query) { if (attribute.Attribute == FileAttribs.None) { continue; } status.HandledItems = 0; status.Stage = attribute.Name; progress.Report(status); groupsBuffer.Clear(); foreach (FilesGroup group in this) { groupsBuffer.Add(group); } this.Clear(); foreach (FilesGroup group in groupsBuffer) { List <FilesGroup> splitResult = await group.SplitByAttribute(attribute, cancelToken, status); foreach (FilesGroup newGroup in splitResult) { this.Add(newGroup); } } m_lastAttributeUsedForGrouping = attribute; } }