Приложение MFC зависает при обновлении CListCtrl

У меня есть CListCtrl в моем приложении MFC. Список необходимо обновлять, когда я получаю уведомление с сервера. Обновление списка работает довольно хорошо, когда уведомлений меньше, так как операций в списке меньше. Но в случае большой нагрузки, управление списком и, в свою очередь, приложение зависает.

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

Если кто-то сталкивался с проблемой раньше, пожалуйста, предложите подход для этого случая.


person user2636725    schedule 03.07.2015    source источник
comment
Ну... пользовательский интерфейс зависает, потому что цикл сообщений не может воздействовать на предстоящие события. Вам придется перемещать функции, выполнение которых занимает некоторое время, в рабочие потоки. ... ммм ... может быть и другой способ, но я не уверен в этом. Возможно, можно обрабатывать предстоящие события в отдельном цикле сообщений В вашей функции. Но это может быть плохим дизайном и привести к другим ловушкам.   -  person Mr.Yellow    schedule 03.07.2015
comment
CListCtrl обычно используется для отображения списка элементов, из которых можно выбирать, что подразумевает небольшой довольно статичный список. Мне кажется, что CListCtrl не подходит для того, чего вы пытаетесь достичь. Вместо этого я бы исследовал подход CScrollView, который представляет собой CView с дополнительными функциями для обработки полос прокрутки. Затем создайте список уведомлений, который обновляется по мере поступления уведомлений, и отображайте эти уведомления в видимой области. Другими словами, используйте подход, основанный на представлении документа, где документ представляет собой список уведомлений.   -  person Richard Chambers    schedule 03.07.2015
comment
Вам следует рассмотреть возможность использования виртуального CListCtrl. Этот стиль управления предназначен для больших объемов данных и используется для кэширования данных и отображения только того, что необходимо.   -  person rrirower    schedule 03.07.2015


Ответы (3)


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

person ScottMcP-MVP    schedule 03.07.2015

У меня была аналогичная ситуация, и я решил ее с помощью таймера. Только когда таймер тикал, ListCtrl мог обновляться.

Боковое примечание: вы должны сделать

SetRedraw(FALSE);

перед массовым обновлением

и

SetRedraw(TRUE);

после.

У вас не должно быть самого контрольного чертежа на уровне отдельных элементов при выполнении массовой операции.

person sergiol    schedule 12.07.2015

Используйте Thread. У меня была та же проблема, и я решил ее, просто добавив цикл добавления элементов в функцию clistctrl в потоке. То есть функция POSTMESSAGE() в потоке должна вызываться столько раз, сколько мы хотим добавить элементы. Приложение MFC зависает при добавлении список элементов управления Также обратитесь к приведенной выше ссылке, чтобы получить некоторое представление

person Vivek Abraham    schedule 31.10.2015