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); } }
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; } }
/// <summary> /// Перегруппировывает результаты поиска дубликатов по заданному атрибуту /// </summary> /// <param name="attribute"></param> public async void RegroupResultsByFileAttribute(GroupingAttribute attribute) { _tokenSource = new CancellationTokenSource(); CancellationToken token = _tokenSource.Token; WorkItemHandler workhandler = delegate { Regroup(attribute, token); }; await ThreadPool.RunAsync(workhandler, WorkItemPriority.High, WorkItemOptions.TimeSliced); _duplicatesCollection.Invalidate(); }
private void UpdateGroupingModeList(GroupingAttribute attrib, CheckBoxAction action) { if (action == CheckBoxAction.Checked) { _grouppingAttributes.Add(attrib); } else { _grouppingAttributes.Remove(attrib); SelectedGroupAttrib = _grouppingAttributes.First(); } NotifyPropertyChanged("ResultGrouppingModesList"); }
public FileCompareOptions() { _grouppingAttributes.Add(None); _checkNameOldValue = _checkName; _checkSizeOldValue = _checkSize; _checkCreationDateTimeOldValue = _checkCreationDateTime; _checkModificationDateTimeOldValue = _checkModificationDateTime; _checkContentOldValue = _checkContent; SelectedGroupAttrib = None; CheckName = true; CheckSize = true; }
public async Task RegroupDuplicates(GroupingAttribute attribute, CancellationToken cancelToken) { if (attribute == this.m_lastAttributeUsedForGrouping) { return; } // Соберём все файлы в одну группу FilesGroup allFiles = new FilesGroup(m_progress); foreach (FilesGroup group in this) { foreach (File file in group) { allFiles.Add(file); } } IProgress <OperationStatus> progress = m_progress; OperationStatus status = new OperationStatus { Id = DataModel.SearchStatus.Grouping, HandledItems = 0, TotalItems = allFiles.Count, Stage = attribute.Name }; this.Clear(); if (attribute.Attribute == FileAttribs.None) { this.Add(allFiles); } else { List <FilesGroup> splitResult = await allFiles.SplitByAttribute(attribute, cancelToken, status); for (int i = 0; i < splitResult.Count; i++) { this.Add(splitResult[i]); } } m_lastAttributeUsedForGrouping = attribute; status.Id = DataModel.SearchStatus.GroupingCompleted; progress.Report(status); }
/// <summary> /// Split group to smoll groups with equal value of given attribute /// Выполняем сортировку группы по заданному атрибуту файла /// Сравниваем файлы в группе по заданному атрибуту попарно первый со вторым второй с третьим и тд /// и при равенстве знвчений заданного атрибута добавляем файлы в новую группу /// при первом несовпадении файлов считаем формирование группы файлов совпадающих по заданному атрибуту /// завершенным. /// Если количество файлов в новой группе больше 1, новую группу добавляем в новый список групп /// </summary> /// <param name="attribute"></param> /// <param name="status"></param> /// <param name="cancelToken"></param> /// <returns></returns> public async Task <List <FilesGroup> > SplitByAttribute(GroupingAttribute attribute, CancellationToken cancelToken, OperationStatus status) { Debug.Assert(this.Count >= 2, "SplitByAttributeMethod called on group with less then two files"); IProgress <OperationStatus> progress = _progress; DataModel.SearchStatus oldStatusId = status.Id; status.Id = DataModel.SearchStatus.Sorting; progress.Report(status); await this.SortByAttribute(0, this.Count - 1, attribute.Attribute); status.Id = oldStatusId; var newGroupsCollection = new List <FilesGroup>(); var newgroup = new FilesGroup(_progress); newgroup.Add(_files[0]); ++status.HandledItems; for (int i = 1; i < this.Count; i++) { int compareResult = await _files[i - 1].CompareTo(_files[i], attribute.Attribute); if (compareResult != 0) { if (newgroup.Count > 1) { newGroupsCollection.Add(newgroup); } newgroup = new FilesGroup(_progress); } newgroup.Add(_files[i]); cancelToken.ThrowIfCancellationRequested(); ++status.HandledItems; progress.Report(status); } if (newgroup.Count > 1) { newGroupsCollection.Add(newgroup); } return(newGroupsCollection); }