Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > В чем может быть ошибка при работе с Tchart


Автор: asdnmg7sdkw 11.11.2007, 14:35
Иногда в момент клика по Tchart'у выскакивает ошибка list index out of bounds(x), где x - число похожее на кол-во точек. Причем если применить zoom к небольшому кусочку, то ошибка при клике не появляется.Так же ошибка не появляется если процесс добавления и удаления точек остановлен. Debuger ссылается на строку Application.Run.
В чем может быть ошибка?

Автор: Alexeis 11.11.2007, 16:24
  Программа случаем не многопоточная? Какая делфя?

Автор: asdnmg7sdkw 11.11.2007, 17:18
Цитата

 Программа случаем не многопоточная? Какая делфя? 

Дельфи7, многопоточная.

Автор: Alexeis 11.11.2007, 17:40
  Вероятно что из второго потока происходит работа с Tchart без синхронизации.

Автор: asdnmg7sdkw 11.11.2007, 20:07
Цитата

Вероятно что из второго потока происходит работа с Tchart без синхронизации. 

Из 2-го потока через sendmessage скидываю на основной, а он уже работает с Tchart'ом. Вроде так можно.

Автор: Alexeis 12.11.2007, 00:40
asdnmg7sdkw, смотря чего скидывать. Например, если скидывать адрес (указатель), то все равно будут проблемы, также как если скидывать строку, динамический массив, объект.

Автор: asdnmg7sdkw 12.11.2007, 15:40
Цитата(Alexeis @ 12.11.2007,  00:40)
asdnmg7sdkw, смотря чего скидывать. Например, если скидывать адрес (указатель), то все равно будут проблемы, также как если скидывать строку, динамический массив, объект.

Вообщем в неосновной поток поступают некоторые данные. Например x,y, название точки и некоторая информация о точке. Нужно записать эти данные в глобальный массив и нанести точку на чарт. Вот как это правильно сделать чтобы не возникали проблемы?

Автор: Alexeis 12.11.2007, 15:51
Запись в TChart делать в методе Synchronize второго потока.

Автор: asdnmg7sdkw 12.11.2007, 18:17
а как вызвать процедуру методом Synchronize и передать в нее параметры, если поток создан через BeginThread?

Автор: Alexeis 12.11.2007, 18:38
http://forum.vingrad.ru/index.php?show_type=forum&showtopic=127140

В частности мое решение в предпоследнем посте.

Автор: asdnmg7sdkw 12.11.2007, 20:24
Уточню немного задачу и ход решения. А вы поправьте, там где нужно smile
Задача.
Есть несколько дополнительных потоков и 1 основной. Каждый из дополнительных потоков получает информацию о точках и записывает в глобальный массив. У каждого доп. потока свой номер и соответственно своя ячейка в массиве. Нужно чтобы в чарт выводились точки определенного потока, а остальные просто сохранялись. Изначально выводятся точки 1-го доп. потока, впоследствии пользователь может выбрать другой поток.
Ход решения.
Сначало доп. поток записывает данные в свою ячейку в массиве. Входит в критическую секцию. Записывает номер ячейки в глобальную переменную, чтобы смог найти данные в другой процедуре. Потом запускает процедуру методом synchronize, в которой смотрит действительно ли он тот поток, который должен рисовать в чарте. Если да, то рисуем точки, выходим из процедуры и освобождаем секцию. Если нет то просто выходим. Вдруг пользователь изменил поток который выводит информацию, тогда изменяем значение глобальной переменной, которая означает какой поток должен наносить точки. Очищаем чарт и рисуем точки выбранного потока. Вот тут наверно тоже надо както синхронизировать основной поток с выбранным дополнительным.

Автор: Alexeis 12.11.2007, 21:06
Цитата(asdnmg7sdkw @  12.11.2007,  20:24 Найти цитируемый пост)
Записывает номер ячейки в глобальную переменную, чтобы смог найти данные в другой процедуре.

  Только эта переменная должна быть объявлена как ThreadVar, вместо var, чтобы для каждого потока создалась своя копия.
  
Цитата(asdnmg7sdkw @  12.11.2007,  20:24 Найти цитируемый пост)
Потом запускает процедуру методом synchronize, в которой смотрит действительно ли он тот поток, который должен рисовать в чарте. Если да, то рисуем точки, выходим из процедуры и освобождаем секцию. 

  Правильно.

Цитата(asdnmg7sdkw @  12.11.2007,  20:24 Найти цитируемый пост)
Вдруг пользователь изменил поток который выводит информацию, тогда изменяем значение глобальной переменной, которая означает какой поток должен наносить точки. Очищаем чарт и рисуем точки выбранного потока. Вот тут наверно тоже надо както синхронизировать основной поток с выбранным дополнительным. 


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

Автор: dumb 12.11.2007, 21:52
пуcть доп.потоки только заполняют данные, а отрисовкой лучше заниматься основному потоку.
вызывать Synchronize, находясь в крит.секции - дурно попахивает и тянет на потенциальный deadlock.

Автор: asdnmg7sdkw 12.11.2007, 22:38
Цитата

Только эта переменная должна быть объявлена как ThreadVar, вместо var, чтобы для каждого потока создалась своя копия.

Вообще если будет критическая секция то только 1 поток в нее зайдет и соответственно только 1 поток будет ее использовать. Тогда зачем для каждого своя переменная?
Цитата

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

Что-то до меня не доходит эта идея. Хочу заметить, что дополнительные потоки зациклены. Они периодически добавляют и удаляют точки из массива и только 1 из них добавляет и удаляет их из чарта.

Автор: asdnmg7sdkw 15.11.2007, 20:25
Я забыл 1 деталь. Еще доп. потоки будут перемещать свои точки.
Посмотрите плз что у меня получилось и скажите что сделано не так.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)