saide_a Ответов: 2

Как добавить огромное количество элементов в listctrl с минимальной задержкой?


У меня есть элемент управления списком, который должен добавить к нему около 280000 элементов, а затем отобразить. это занимает около 4 минут для меня, и мой пользовательский интерфейс отключается в течение этого времени.

как я могу уменьшить время задержки?

Что я уже пробовал:

pTable = new CListCtrl;
CString strtemp;
for (unsigned int i = 1; i <= size; i++)
{
    pTable->InsertItem(i, strtemp);
}

2 Ответов

Рейтинг:
20

Jochen Arndt

Кто будет читать (и прокручивать) 280 000 пунктов?

Решением будет использование виртуального элемента управления списком, который обрабатывает только те элементы, которые действительно видны. Видеть Элементы Управления Виртуальными Списками | Microsoft Docs[^].

Для невиртуального элемента управления списком вы можете (и всегда должны даже с меньшими списками) отключить обновление экрана при изменении списка:

pTable->SetRedraw(FALSE);

// Modify list here

pTable->SetRedraw(TRUE);

// Invalidate the entire list
pTable->Invalidate();
// Force painting
pTable->UpdateWindow();


[РЕДАКТИРОВАТЬ]
Зная заранее количество предметов, используйте SetItemCount() первоначально. Даже если вы не знаете счет заранее, это может быть, наконец, быстрее, чтобы определить и установить его.

Для дальнейших улучшений сделайте код внутри цикла как можно более быстрым (простым). Это включает в себя избегание любой функции, которая выделяет память в цикле. Используйте, например, предварительно CStrings или буферы обычного текста, определенные вне цикла с помощью параметра max. возможная длина строки. Если это возможно, избегайте также любой функции форматирования строк.
[/РЕДАКТИРОВАТЬ]


saide_a

это список 8-байтовых сообщений в 4 МБ памяти.

Jochen Arndt

Память не заботится, пока нет подкачки. Какая разница, кто читает такие большие списки.

Отключение перерисовки значительно ускорит процесс. Если этого недостаточно, вы должны использовать виртуальный список или меньшие списки.

KarstenK

Виртуальный элемент управления списком является правильным решением и загружает только те данные, которые необходимо отобразить. Загрузка всех данных означает загрузку большого количества вещей, которые не отображаются на экране и замедляют работу вашего приложения.

Всегда помните: listcontrol создан не для массивных данных, а для небольшого снимка для пользователя.

saide_a

Большое спасибо ,я использовал виртуальный список, как описано в этой ссылке https://www.codeproject.com/Articles/7891/Using-virtual-lists

Рейтинг:
2

Ajcek84

Рассматривали ли вы пейджинг или бесконечную прокрутку? Элементы могут быть созданы/извлечены в другом потоке, но обновление элемента управления всегда блокирует поток пользовательского интерфейса, если этот элемент управления не поддерживает какую-либо виртуализацию. Лучший подход-добавлять элементы по частям (например, 200 элементов одновременно), но вы должны решить, когда добавлять конкретную деталь: один подход-это подкачка. Вы также можете добавить следующий пакет o элементов, когда пользователь прокручивает его вниз (бесконечная прокрутка).


saide_a

В моем случае почти всегда требуется полная прокрутка, только при щелчке "открыть" я хочу, чтобы список обновил шоу, а в другом потоке ничего не связано с listctrl. что вы предлагаете для меня?