Привет всем! Отображаю таблицу и периодически обновляю аттрибуты элементов при помощи ListViev_SetItem или ListViev_SetItemText. Проблема заключается в том, что в некоторый момент попытка обновить элемент приводит к зависанию всей программы, хотя на данном этапе к таблице имеет доступ только один поток. Чем может быть вызвано такое поведение?
Подробнее. В каком событии (в какой момент времени) меняшь?
Здравствуйте, Wolodimir, Вы писали:
W>Привет всем! Отображаю таблицу и периодически обновляю аттрибуты элементов при помощи ListViev_SetItem или ListViev_SetItemText. Проблема заключается в том, что в некоторый момент попытка обновить элемент приводит к зависанию всей программы, хотя на данном этапе к таблице имеет доступ только один поток. Чем может быть вызвано такое поведение?
Здравствуйте, dkotov, Вы писали:
D>Подробнее. В каком событии (в какой момент времени) меняшь?
Поток проверяет базу данных на наличие изменений и создает очередь строк, которые нужно обновить. После этого в цикле вызывается следующий метод:
bool clGuiTable::put_item(string sText, int x, int y)
{
vector<char> vText(sText.begin(), sText.end());
vText.push_back('\0');
if(y<iHeight || y>=0)
ListView_SetItemText(hListView, y, x, &vText[0]);
return true;
};
заранее не известно, сколько раз получится обновить элемент.
но в какой-то момент макрос попросту ничего не возвращает. то же саме происходит, если использовать SendMessage.
GUI'шный поток и поток обновляющий/проверяющий — это один и тот же?
Здравствуйте, Wolodimir, Вы писали:
W>Здравствуйте, dkotov, Вы писали:
D>>Подробнее. В каком событии (в какой момент времени) меняшь?
W>Поток проверяет базу данных на наличие изменений и создает очередь строк, которые нужно обновить. После этого в цикле вызывается следующий метод:
W>bool clGuiTable::put_item(string sText, int x, int y) W>{ W> vector<char> vText(sText.begin(), sText.end()); W> vText.push_back('\0');
W> if(y<iHeight || y>=0) W> ListView_SetItemText(hListView, y, x, &vText[0]);
W> return true; W>};
W>заранее не известно, сколько раз получится обновить элемент. W>но в какой-то момент макрос попросту ничего не возвращает. то же саме происходит, если использовать SendMessage.
То-то и оно. Взаимодействовать с UI'ными элементами необходимо в UI'ном потоке.
Здравствуйте, Wolodimir, Вы писали:
W>Здравствуйте, dkotov, Вы писали:
D>>GUI'шный поток и поток обновляющий/проверяющий — это один и тот же?
W>нет, это разные потоки
1. получаем портянку данных
2. входим в критическую секцию
3. кладем данные в хранилище
4. PostMessage(HandleГлавногоОкна, WM_USER + 1, 0, 0);
5. выходим из критической секции
UI-поток (основное окно)
1. ловим WM_USER + 1
2. входим в критическую секцию
3. обновляем
4. выходим из критической секции
Здравствуйте, Wolodimir, Вы писали:
W>Здравствуйте, dkotov, Вы писали:
D>>То-то и оно. Взаимодействовать с UI'ными элементами необходимо в UI'ном потоке.
W>спасибо за подсказку! попробую организовать проверку в оконной процедуре основного окна и отпишусь
Оконная процедура:
1. входим в критическую секцию
2. получаем данное (по идентификатору)
3. покидаем критическую секцию
4. записываем текст в ячейку
но ошибка не устранена. кажется, какая-то фигня с критическими секциями.
если приостановить программу, то поток останавливается в этом месте:
mlock.c -> void __cdecl _lock(int locknum)
при этом компилятор (VS2010) показывает сообщение "Процесс деактивирован. Все потоки завершены"
D>PS: Один из самых простых способов — PostMessage
D> Обновляющий поток (псевдо-код):
D> 1. получаем портянку данных D> 2. входим в критическую секцию D> 3. кладем данные в хранилище D> 4. PostMessage(HandleГлавногоОкна, WM_USER + 1, 0, 0); D> 5. выходим из критической секции
D> UI-поток (основное окно)
D> 1. ловим WM_USER + 1 D> 2. входим в критическую секцию D> 3. обновляем D> 4. выходим из критической секции