Проблемма в следующем: при быстрой перерисовке части окна (чаще чем 50 мс) иногда происходит зависание. Точнее оно происходит при попытке масштабировать окно или при перекрывании части окна окном другой программы.
Рабочее окно содержит несколько TPanel с align:= alClient или alTop.
Похоже что зависание происходит когда эти панели пытаются перерисоваться. Но отловить ошибку не могу :?
Быстрая перерисовка в Delphi
Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду
- Naeel Maqsudov
- Сообщения: 2570
- Зарегистрирован: 20 фев 2004, 19:17
- Откуда: Moscow, Russia
- Контактная информация:
Код в студию!
Экстрасенсов тут, как мне кажется нет.
Дело явно не в перерисовке как таковой, а в том, что еще делает процедура, которая инициирует перерисовку....
Как проявляется зависание? Это приостановка работы или совершенное зависание приложения, требующее его выгрузки и перезапуска? Сопровождается ли оно какими-либо сообщениями об ошибках?
Экстрасенсов тут, как мне кажется нет.
Дело явно не в перерисовке как таковой, а в том, что еще делает процедура, которая инициирует перерисовку....
Как проявляется зависание? Это приостановка работы или совершенное зависание приложения, требующее его выгрузки и перезапуска? Сопровождается ли оно какими-либо сообщениями об ошибках?
В процедуре отрисовки выполняются только
LineTo(…
MoveTo(…
Polyline(…
Но вызывается процедура внешней программой, точнее драйвером звуковой карты, то есть асинхронно и с достаточно высокой частотой.
Зависание происходит молча, без сообщений. Зависание приложения, выход только перезагрузка приложения.
Удалось добиться повторяемости зависания – когда перекрывающее окно полностью открывает область отрисовки. Я так понимаю вызывается repaint окна и тут вызывается моя процедура отрисовки и тут …
LineTo(…
MoveTo(…
Polyline(…
Но вызывается процедура внешней программой, точнее драйвером звуковой карты, то есть асинхронно и с достаточно высокой частотой.
Зависание происходит молча, без сообщений. Зависание приложения, выход только перезагрузка приложения.
Удалось добиться повторяемости зависания – когда перекрывающее окно полностью открывает область отрисовки. Я так понимаю вызывается repaint окна и тут вызывается моя процедура отрисовки и тут …
- Naeel Maqsudov
- Сообщения: 2570
- Зарегистрирован: 20 фев 2004, 19:17
- Откуда: Moscow, Russia
- Контактная информация:
Т.е. как бы получается, что к моменту, когда надо в следующий раз сделать repaint у Вас еще первый не завершился...
Если Вы (точнее рабочая станция на которой тестируется приложение) не можете обеспечить достаточно быстрое рисование функциями GDI, то надо либо прореживать попытки рисования, либо использовать другие методы подготовки изображений (если это конечно возможно).
Например, попробуем для начала не быстрее рисовать, а избавиться от зависания. Допустим процедура, которая выпоняет некое рисование у Вас в коде выделена как отдельная (скорее всего это так и есть). По пробуйте ее реорганизовать так, чтобы во время ее выполнения другие вызовы этой же процедуры ничего не делали.
Самый простой способ:
Правда если повторный вызов произойдет между if и flg:=false то получится тоже плохая ситуация (хотя и весьма весьма маловероятная).
Можно также использовать объекты синхронизации, которые специально для таких вещей предназначены.
Семафоры, например. Создать семафор в момент инициализации формы, такой, чтобы "только один поезд пропускал", если можно так выразиться. В начале процедуры занимать семафор, а в конце отпускать. А если занять не удалось, то делать выход их процедуры. Т.е. (продолжая железнодорожную
аналогию) если семафор закрыт, то поезд под откос, чтобы путь не занимал 
см CreateSemaphore и связанные функции
Вообще хотельсь бы заметить, что перерисовка чаще 10 раз в секунду в большинстве задач не имеет смысла, так как глазу обычного человека это как-то не очень вообще заметно. Также перерисовка с частотой выше частоты развертки (от 50Гц до "у кого как") тоже не имеет смысла, так как на мониторе не сможет быть адекватно воспроизведена...
Если Вы (точнее рабочая станция на которой тестируется приложение) не можете обеспечить достаточно быстрое рисование функциями GDI, то надо либо прореживать попытки рисования, либо использовать другие методы подготовки изображений (если это конечно возможно).
Например, попробуем для начала не быстрее рисовать, а избавиться от зависания. Допустим процедура, которая выпоняет некое рисование у Вас в коде выделена как отдельная (скорее всего это так и есть). По пробуйте ее реорганизовать так, чтобы во время ее выполнения другие вызовы этой же процедуры ничего не делали.
Самый простой способ:
Код: Выделить всё
const flg:boolean=true;
procedure XXXXX;
begin
if flg then begin
flg:=false;
try
//что-то делаем
finally
flg:=true;
end;
end;
end;
Можно также использовать объекты синхронизации, которые специально для таких вещей предназначены.
Семафоры, например. Создать семафор в момент инициализации формы, такой, чтобы "только один поезд пропускал", если можно так выразиться. В начале процедуры занимать семафор, а в конце отпускать. А если занять не удалось, то делать выход их процедуры. Т.е. (продолжая железнодорожную


см CreateSemaphore и связанные функции
Вообще хотельсь бы заметить, что перерисовка чаще 10 раз в секунду в большинстве задач не имеет смысла, так как глазу обычного человека это как-то не очень вообще заметно. Также перерисовка с частотой выше частоты развертки (от 50Гц до "у кого как") тоже не имеет смысла, так как на мониторе не сможет быть адекватно воспроизведена...
Спасибо з асодержательный ответ
Действительно, частота перерисовки выше 10 Гц смысла не имеет. У меня источник информации инициировал перерисовку и это не правильно, поэтому я и обратился на форум
Еще раз спасибо за ответ.
Действительно, частота перерисовки выше 10 Гц смысла не имеет. У меня источник информации инициировал перерисовку и это не правильно, поэтому я и обратился на форум
Еще раз спасибо за ответ.