Добрый день!
Есть ListBox на 30 000 записей. Записи загружаются из DataTable, который в свою очередь формируется путем чтения базы данных.
Во время заполнения ListBox проходит порядка 3 и более секунд. При этом путем экспериментов выяснилось, что около 80% времени тратится на отрисовку ListBox и 20% на выборку данных из базы.
Собственно, вопрос. Как ускорить процесс заполнения ListBox, либо обойти подвисание программы.
Здравствуйте, Andir, Вы писали: A>Ответ простой: не загружать в ListBox — 30 тыс. элементов, всё равно никто в нормальном состоянии не сможет столько записей просмотреть. A>С Уважением, Andir!
Да, собственно и не спорю. Но как организовать тогда частичную загрузку и как подгружать элементы при прокрутке ScrollBar-а.
Ну хотят они (типа заказчики), чтоб СПИСОК ВСЕХ АДРЕСОВ БЫЛ ПЕРЕД ГЛАЗАМИ. Это несмотря на то, что реализован вполне достойный поиск.)
Здравствуйте, sazar, Вы писали:
A>>Ответ простой: не загружать в ListBox — 30 тыс. элементов, всё равно никто в нормальном состоянии не сможет столько записей просмотреть. S>Да, собственно и не спорю. Но как организовать тогда частичную загрузку и как подгружать элементы при прокрутке ScrollBar-а.
Попробовать виртуальный режим в ListView. Или реализовать виртуальный ListBox (например, здесь).
S>Ну хотят они (типа заказчики), чтоб СПИСОК ВСЕХ АДРЕСОВ БЫЛ ПЕРЕД ГЛАЗАМИ. Это несмотря на то, что реализован вполне достойный поиск.)
Попробуй узнать, зачем он им нужен (какую задачу он бы решал для них) весь. Например, им, возможно, хочется на самом деле быстро искать нужную запись по первым буквам…
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, sazar, Вы писали:
S>Здравствуйте, Andir, Вы писали: S>Ну хотят они (типа заказчики), чтоб СПИСОК ВСЕХ АДРЕСОВ БЫЛ ПЕРЕД ГЛАЗАМИ. Это несмотря на то, что реализован вполне достойный поиск.)
Требование возникло оттого, что заказчики думают, что в состоянии охватить взглядом весь список. Это иллюзия — так создайте для них ещё одну иллюзию, что список всех адресов у них перед глазами. Кроме того, сделайте поиск (то есть фильтр записей) максимально удобным — начинающим искать, как только пользователь начал печатать (incremental search), с подсветкой подходящих записей, с возвратом к предыдущему экрану после отмены (по нажатию Esc, например). Может, в вашей программе поиском банально неудобно пользоваться — например, он требует вводить кучу параметров через диалоговое окно.
Отображайте записей в списке ровно на один экран, подгружайте другие, когда пользователь прокручивает список или осуществляет поиск. Кажется, для этого можно сделать умный прокси на основе BindingList.
Здравствуйте, Vladek, Вы писали:
V>Требование возникло оттого, что заказчики думают, что в состоянии охватить взглядом весь список. Это иллюзия — так создайте для них ещё одну иллюзию, что список всех адресов у них перед глазами. Кроме того, сделайте поиск (то есть фильтр записей) максимально удобным — начинающим искать, как только пользователь начал печатать (incremental search), с подсветкой подходящих записей, с возвратом к предыдущему экрану после отмены (по нажатию Esc, например). Может, в вашей программе поиском банально неудобно пользоваться — например, он требует вводить кучу параметров через диалоговое окно.
В программе как раз и реализован incremental search, оставляющий только необходимые записи.
V>Отображайте записей в списке ровно на один экран, подгружайте другие, когда пользователь прокручивает список или осуществляет поиск. Кажется, для этого можно сделать умный прокси на основе BindingList.
Спасибо за BindingList. Сейчас посмотрю. Я как раз и имел ввиду способ загрузки только одного экрана и подгрузки другого при прокручивании списка. Просто ни разу не реализовывал такое, поэтому и спрашиваю.
Здравствуйте, sazar, Вы писали:
S>Добрый день! S>Есть ListBox на 30 000 записей. Записи загружаются из DataTable, который в свою очередь формируется путем чтения базы данных. S>Во время заполнения ListBox проходит порядка 3 и более секунд. При этом путем экспериментов выяснилось, что около 80% времени тратится на отрисовку ListBox и 20% на выборку данных из базы. S>Собственно, вопрос. Как ускорить процесс заполнения ListBox, либо обойти подвисание программы.
как вариант загрузить первые 5 000 записей потом серединку 5 000 и конец 5 000 и надеется что никто не спалит
Можно юзать потоки говорят спасает от подвисонов, или отказаться от .Net и сделать на другой платформе которая не висит как шланг на стенке
и не жрет память как собака
Здравствуйте, Max1983, Вы писали:
M>Здравствуйте, sazar, Вы писали:
M>Можно юзать потоки говорят спасает от подвисонов, или отказаться от .Net и сделать на другой платформе которая не висит как шланг на стенке M>и не жрет память как собака
1.действительно, можно в другом потоке заполнять список в фоне. т.е. пользователь сможет просматривать список паралельно с его заполнением. все равно же сразу пользователь в конец списка не полезет. да даже и если полезет, то тогда уж будет ждать пока список не завершит формироваться.
2.может на списке какие-либо обработчики висят и срабатывают при добавлении в список записи? для обычного компа 30 тысяч записей все же не проблема, чтобы 3 секунды заполнять. Может на время заполнения видимость списка отключить?
Здравствуйте, kvl_mikki, Вы писали:
_> Может на время заполнения видимость списка отключить?
Или прогресс бар показать в окошке а лист сделать Dizable.
Да нет! Надо просто спрятать всю форму..
И в ето время запустить какое то видео, в отдельной форме чтоб пока юзер ждет — мог кино глянуть
Здравствуйте, sazar, Вы писали:
S>Да, собственно и не спорю. Но как организовать тогда частичную загрузку и как подгружать элементы при прокрутке ScrollBar-а. S>Ну хотят они (типа заказчики), чтоб СПИСОК ВСЕХ АДРЕСОВ БЫЛ ПЕРЕД ГЛАЗАМИ. Это несмотря на то, что реализован вполне достойный поиск.)
Ну, вот ListView в Win32, к примеру, поддерживает Virtual Mode ажно с 1998 года. А ListBox вообще давно пора запретить
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Max1983, Вы писали:
M>Можно юзать потоки говорят спасает от подвисонов, или отказаться от .Net и сделать на другой платформе которая не висит как шланг на стенке M>и не жрет память как собака
Есть уверенность в том, что проблема именно в .net? Или к чему это было сказано?
Здравствуйте, Max1983, Вы писали:
M>Здравствуйте, kvl_mikki, Вы писали:
_>> Может на время заполнения видимость списка отключить?
M>Или прогресс бар показать в окошке а лист сделать Dizable. M>Да нет! Надо просто спрятать всю форму.. M>И в ето время запустить какое то видео, в отдельной форме чтоб пока юзер ждет — мог кино глянуть
Нет, ты не понял идею- отключение видимости, не просто дизэйбл, а отключение, позволит не тратить время на прорисовку еще не сформировавшегося списка. В теории это может ускорить загрузку, так что никакого прогресс бара не надо будет. Если все сократится до милисекунд, то пользователь вообще не увидит моргания от процедуры вкл/откл списка. Если это не так, т.е. видимость никак не влияет на скорость заполнения, то тогда вариант с паралельным потоком.
Здравствуйте, sazar, Вы писали:
S>Добрый день! S>Есть ListBox на 30 000 записей. Записи загружаются из DataTable, который в свою очередь формируется путем чтения базы данных. S>Во время заполнения ListBox проходит порядка 3 и более секунд. При этом путем экспериментов выяснилось, что около 80% времени тратится на отрисовку ListBox и 20% на выборку данных из базы. S>Собственно, вопрос. Как ускорить процесс заполнения ListBox, либо обойти подвисание программы.
1) Использовать ListView.
2) Ограничить показ записей, предложив использовать более точный поиск/фильтр.
3) Производить загрузку данных между вызовами BeginUpdate/EndUpdate.
4) При необходимости использовать виртуальный режим (VirtualMode = true) и реализовать свой алгоритм загрузки данных.
Здравствуйте, sazar, Вы писали:
S>Да, собственно и не спорю. Но как организовать тогда частичную загрузку и как подгружать элементы при прокрутке ScrollBar-а. S>Ну хотят они (типа заказчики), чтоб СПИСОК ВСЕХ АДРЕСОВ БЫЛ ПЕРЕД ГЛАЗАМИ. Это несмотря на то, что реализован вполне достойный поиск.)
Заказчики — однозначно маньяки. По моему легче из убедить что это им это не нужно.
если в массиве больше 100-200 записей то надо организовывать поиск по списку и прочий сопутстующий сервис. Мороки выше крыши.
Здравствуйте, sazar, Вы писали:
S>Собственно, вопрос. Как ускорить процесс заполнения ListBox, либо обойти подвисание программы.
ИМХО, 3 секунды на 30 000 записей — это более чем нормально.
Тут кто-то упоминал, обязательно использовать BeginUpdate & EndUpdate. Это уберет ненужные отрисовки в процессе загрузки
Ну и сплэш какой-нить повесить, типа Wait, please
PS: А вообще 30000 записей в одном листе — ну точно маньяки.
Здравствуйте, olegyershov, Вы писали:
O>PS: А вообще 30000 записей в одном листе — ну точно маньяки.
Ничего особенного. Задач требующих таких вещей хватает. Когда какой-нибудь мегабаланс не сходится, например. Приходится тупо всю "лыжню" последовательно изучать. Грамотные поиски, группировки, цветовыделение и т.п. ситуацию облегчают, но необходимости иметь механизм эффективно показывающий все записи не отменяют.
Здравствуйте, drol, Вы писали:
D>Ничего особенного. Задач требующих таких вещей хватает. Когда какой-нибудь мегабаланс не сходится, например. Приходится тупо всю "лыжню" последовательно изучать. Грамотные поиски, группировки, цветовыделение и т.п. ситуацию облегчают, но необходимости иметь механизм эффективно показывающий все записи не отменяют.
В отчете — может быть. Будет такая себе пухленькая папочка а в оперативном списке на форме — я извиняюсь. Его даже листать будет проблематично.
"...всю "лыжню" последовательно изучать..." — оптимист. Да на 3-й сотне записей уже крышу снесет. Для поиска ошибок есть другие более эффективные способы.
Я за свою практику тоже писал немало "прикладнух" (в том числе и для бухгалтерий) и всегда обходился небольшими списками, путем наложения всяких фильтров.
а с переходом на клиент-серверные СУБД такие длиннючие списки просто фатально вредны, т.к. система становтся совершенно неповоротливая. Независимо от того, на каком языке она написана.
Здравствуйте, olegyershov, Вы писали:
O>Его даже листать будет проблематично.
Да ну. Нормально виртуализованный — никаких особых проблем.
O>"...всю "лыжню" последовательно изучать..." — оптимист. Да на 3-й сотне записей уже крышу снесет.
Это Вам или мне снесёт. Однако в мире навалом и людей "обожающих тупую и однообразную работу"
O>а с переходом на клиент-серверные СУБД такие длиннючие списки просто фатально вредны, т.к. система становтся совершенно неповоротливая. Независимо от того, на каком языке она написана.
Не смешите. Какие-то жалкие 30000 записей. Нормальная система и не заметит.
Здравствуйте, drol, Вы писали:
D>Не смешите. Какие-то жалкие 30000 записей. Нормальная система и не заметит.
Вопрос не в скорости выборки, а в скорости передачи данных от сервера к клиентовсому приложению. Особенно если сеть хреновая. И клиентовская машинка на ладан дышит. Что, в общем-то, тоже не редкость, к сожалению.
Так — лирическое отсупление:
Была у меня как-то базешка. самая большая таблица как раз где-то 20-25 тыс записей была. Дык при выдаче одного мудреного отчета сервер молотил минут 5 не меньше. так что — it depends
Ошибку мы потом нашли все таки (хотя далеко не сразу) и повысили скорость до 3-5 секунд проблема была не критичная, т.к. при выдаче отчета и подождать можно.