public int GetItemSortedPosition(int index, object sender)
{
IComparer comparer = GetSortComparer();
if (comparer == null)
return index;
if (_list.Count > 1)
for (int i = 0; i < _list.Count; i++)
if (i != index)
{
if (comparer.Compare(_list[i], sender) > 0)
{
if (i > 0)
return i - 1;
return i;
}
}
return _list.Count - 1;
}
ЗЫ: я не сказал в чём ошибка
Имеем отсортированный список. Значения поля, по которому идёт сортировка:
1, 1, 2, 3
Если производим замену объекта с индексом 0, на объект со значением поля 2, то он встанет по индексу 3, а должен по индексу 2.
Получается:
1, 2, 3, 2
А должно быть:
1, 2, 2, 3
Т. е. возвращается индекс на единицу больше правильного.
Замену объекта произвожу командой myBindingSource[0] = myObj;
Re[3]: Ошибка в BLToolkit.ComponentModel.BindingListImpl
Ещё один момент не учёл. Теперь вроде всё правильно.
public int GetItemSortedPosition(int index, object sender)
{
IComparer comparer = GetSortComparer();
if (comparer == null)
return index;
if (_list.Count > 1)
for (int i = 0; i < _list.Count; i++)
if (i != index && comparer.Compare(_list[i], sender) > 0)
{
if (i > 0 && i > index)
return i - 1;
return i;
}
return _list.Count - 1;
}
Re[4]: Ошибка в BLToolkit.ComponentModel.BindingListImpl
Напишите, пожалуйста, нормальный unit test, который наглядно проиллюстрирует что же именно не так работает.
А то может это и не баги вовсе а фичи такие.
Здравствуйте, Блудов Павел, Вы писали:
БП>Здравствуйте, Rollback!
БП>Напишите, пожалуйста, нормальный unit test, который наглядно проиллюстрирует что же именно не так работает. БП>А то может это и не баги вовсе а фичи такие.
Повторюсь:
Имеем отсортированный список. Значения поля, по которому идёт сортировка:
1, 1, 2, 3
Если производим замену объекта с индексом 0, на объект со значением поля 2, то он встанет по индексу 3, а должен по индексу 2.
Получается:
1, 2, 3, 2
А должно быть:
1, 2, 2, 3
Т. е. возвращается индекс на единицу больше правильного.
Замену объекта произвожу командой myBindingSource[0] = myObj;
Здравствуйте, Rollback, Вы писали:
R>Имеем отсортированный список. Значения поля, по которому идёт сортировка: R>1, 1, 2, 3
R>Если производим замену объекта с индексом 0, на объект со значением поля 2, то он встанет по индексу 3, а должен по индексу 2.
R>Получается: R>1, 2, 3, 2
R>А должно быть: R>1, 2, 2, 3
R>Т. е. возвращается индекс на единицу больше правильного.
R>Замену объекта произвожу командой myBindingSource[0] = myObj;
Спасибо большое, что вы нашли и указали на ошибку, и предложишили решение. Однако, непонятно зачем было переписывать весь метод, не вникая зачем в нем была дополнительная логика (наверное это наша русская особенность ).
BLToolkit используется в Trading приложении в одном весьма не маленьком банке, и после забора нового кода, я долго пытался понять, почему приложение вдруг перестало быть отзывчивым, UI замерирал на мгновения и тому подобные симптомы, и это в тестовом окружении (значительно меньше объемы данных). А оказалось... Если вы посмотрите на начальный код, а именно:
int result = index > 0 ? comparer.Compare(_list[index - 1], sender) : -1;
int nextResult = index < _list.Count - 1 ? comparer.Compare(_list[index + 1], sender) : 1;
if (result > 0 || nextResult < 0)
То вы наверное заметите, что прежде, чем искать позицию, код проверял, надо ли вообще искать новое место, может объект надо оставить на месте. Представте себе список не из 10 объектов, а из нескольких тысяч по меньшей мере. Затем представте, что приложение отображает trades и их изменения в Real-Time, т.е. обноволений много и они происходят часто, иногда до 20 за секунду, в результате OnPropertyChanged (место откуда чаще всего дергается метод) вызвается несчислимое число раз. Далее представте, что поле по которому происходит сортировка — это не простое Property, а довольно сложное комплексное поле. В результате представте сколько лишних сравнений сделает эта функция, если к примеру сортировка идет по одному полю, а меняется другое поле.
Т.е. вместо того чтобы сделать два сравнения максимум, мы просто так делаем неколько тысяч сравнений на каждый чих.
На самом деле починить проблему можно было очень просто.
Вместо:
if (index == i - 1)
return index;
Надо было всего лишь, как вы правильно заметили:
if (i > index)
return i - 1;
Так, что с вашего позволения я все-таки верну на место эту логику за исключением вышеописанного изменения.
Борис.
... << RSDN@Home 1.2.0 alpha rev. 693>>
Re[4]: Ошибка в BLToolkit.ComponentModel.BindingListImpl