Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Зависает API функция EnterCriticalSection [D5, WinXP]


Страницы:   1 2

Unknown user ©   (2007-12-12 17:37:00) 

Рисую из созданного мной потока на канве и почему-то периодически программа зависает. Более подробные поиски выявили, что зависает программа при вызове TPen.Assign при входе в критическую секцию.

Не гарантирую, что код отвечающий за отрисовку потокобезопасный, слишком он сложен и запутан.

Что посоветуете?


tesseract   (2007-12-13 16:36:00) [1]


> Картинку для рисования можешь готовить как угодно, в том
> числе и в отдельном потоке. Когда кадр для прорисовки готов,
>  отдавай контролу картинку и вызывай Invalidate.


А я что предлагал ?


> Пусть WM_PAINT приходит тогда, когда решит нужным система.
>  Не насилуй технику.


Его контролу просто послать можно. Или вызвать Refresh/Repaint.


DiamondShark   (2007-12-13 13:26:00) [2]


> Жду предложений по упрощению.

Убери из OnPaint одного контрола вызов прорисовки второго контрола.
OnPaint должен рисовать только то, что относится к себе.

Картинку для рисования можешь готовить как угодно, в том числе и в отдельном потоке. Когда кадр для прорисовки готов, отдавай контролу картинку и вызывай Invalidate.

Пусть WM_PAINT приходит тогда, когда решит нужным система. Не насилуй технику.


Сергей М.   (2007-12-13 13:23:00) [3]


> канва визуального контрола в дополнительном окне


Canvas - это имя поля класса TMapDrawThread ?
Если да, то где и как оно инициализируется в созданном тобой объекте класса TMapDrawThread ?


Eraser   (2007-12-13 13:17:00) [4]


> Unknown user ©   (13.12.07 12:53) [17]


> Procedure TMapDrawThread.Draw;begin Canvas.Draw(0,0,BMP);
> end;

убрать в OnPaint второго окна. зачем себе жизнь усложнять то? Такой механизм прорисовки (через WM_PAINT) придуман не просто так.


Unknown user   (2007-12-13 12:53:00) [5]


> Метод канвы какого объекта ты здесь вызываешь ?


канва визуального контрола в дополнительном окне.


Сергей М.   (2007-12-13 12:41:00) [6]


> Procedure TMapDrawThread.Draw;
> begin
> Canvas.Draw(0,0,BMP);
> end;
>


Метод канвы какогообъекта ты здесь вызываешь ?
Из кода это неочевидно ..


Unknown user   (2007-12-13 12:34:00) [7]


> А нафиг тогда крит.секция, если фигурирует Synchronize  
> ?
>
> Ты же все равно после формирования битмапа передаешь его
> в осн.поток, который собссно и отрисовывает готовый битмап
> на канве виз.контрола.
>
> Т.е. у тебя к канве битмапа в каждый момент времени обращается
> только один поток, что не требует никакой синхронизации.
>


Критическая секция вызывается неявно в процедуре рисования (посмотрите к примеру VCL код TPen.Assign)

Synchronize использую только при копировании уже отрисованного в битмапе изображения на канвас контрола.


Synchronize(Draw);

Procedure TMapDrawThread.Draw;
begin
Canvas.Draw(0,0,BMP);
end;



> каким образом это происходит?


Да просто все происходит

procedure T.OnPaint
.
.
нарисовали, вызываем рисование во втором окне
SecondDraw
end;


> по-моему все слегка усложнено )


Жду предложений по упрощению.


Eraser   (2007-12-13 11:12:00) [8]


> Unknown user ©   (13.12.07 11:03) [12]


> которая после отрисовки в основном окне вызывает процедуру
> рисования в дополнительном окне

каким образом это происходит?
и каким образом осуществляется прорисовка в доп. окне.. есть Synchronize'ы?

по-моему все слегка усложнено )


Сергей М.   (2007-12-13 11:09:00) [9]


> вторичный поток рисует в памяти на канве битмапа


А нафиг тогда крит.секция, если фигурирует Synchronize  ?

Ты же все равно после формирования битмапа передаешь его в осн.поток, который собссно и отрисовывает готовый битмап на канве виз.контрола.

Т.е. у тебя к канве битмапа в каждый момент времени обращается только один поток, что не требует никакой синхронизации.


Eraser   (2007-12-13 11:03:00) [10]


> ыы   (13.12.07 10:42) [6]

а ты посмотри код функции обработчика WM_SYSCOLORCHANGE в TWinControl по-моему (у меня просто Делфи нет под рукой), сразу все понятно станет, очень непотокобезопасная штука )


Unknown user   (2007-12-13 11:03:00) [11]


> странная методика.. по-моему нужно использовать InvalidateRect,
>  а в OnPaint прорисовывать.


Так в OnPaint и прорисовывается. Ладно, наверно я недостаточно ясно выражаюсь, распишу поэтапно:

1. В окно визуального контрола основного окна приходит сообщние WM_PAINT
2. Вызывается процедура OnPaint которая после отрисовки в основном окне вызывает процедуру рисования в дополнительном окне (отображается не одна и та же информация).
3. Рисование в дополнительном окне реализовано в отдельном потоке, рисование просиходит не напрямую в канвас виз. контрола а через битмап.
4. Рисование в основном окне имеет приоритет (не должно быть подтормаживаний).

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


ыы   (2007-12-13 10:58:00) [12]

Eraser, ответь на [6] плз!


Eraser   (2007-12-13 10:54:00) [13]


> Unknown user ©   (13.12.07 10:44) [7]


> после окончания рисования с использованием Synchronize копирует
> битмап в канвас другого визуального контрола.

странная методика.. по-моему нужно использовать InvalidateRect, а в OnPaint прорисовывать.


Unknown user   (2007-12-13 10:46:00) [14]


> Как можно прерывать рисование в дополнительном окне?


Я имел ввиду без использования дополнительных потоков.


Unknown user   (2007-12-13 10:44:00) [15]

> Сергей М. & tesseract

Основной поток рисует на канве визуального контрола, вторичный поток рисует в памяти на канве битмапа, после окончания рисования с использованием Synchronize копирует битмап в канвас другого визуального контрола.

Как можно прерывать рисование в дополнительном окне? Насколько я понимаю использование Application.ProcessMessages внутри процедуры рисования чревато непредсказуемым поведением?


ыы   (2007-12-13 10:42:00) [16]


> по-хорошему надо перехватывать сообщение WM_SYSCOLORCHANGE
А это к чему? Или это надо понимать как "дополнительно к рисованию на канве ещё надо..."?


tesseract   (2007-12-13 10:24:00) [17]


> задача же дополнительного сводится к подготовке данных для
> рисования, а не к собственно рисованию.


Дополню : В доп потоке созаеться область для BitBlt, передаеться в основной поток, где она уже просто вставляеться в область. "На пальцах",  примерно, как в DoubleBuffered у формы - сначала готовиться картинка, а в onpiant вклеиваем.


Сергей М.   (2007-12-13 10:20:00) [18]


> может можно обойтись без рисования в отдельном потоке?


Не только можно обойтись, но и нельзя этого делать вообще.

Рисовать на канве виз.контрола в VCL-приложении имеет право и обязан основнойпоток, задача же дополнительного сводится к подготовке данных для рисования, а не к собственно рисованию.


Unknown user   (2007-12-13 10:12:00) [19]

А может можно обойтись без рисования в отдельном потоке? Задача такая: рисование происходит в основном и дополнительном окне. Рисование в основном окне должно иметь больший приоритет, то есть при необходимости перерисовки в основном окне рисование в дополнительном должно приостанавливаться или прекращаться. Как это можно реализовать?


Unknown user   (2007-12-12 18:14:00) [20]

> Eraser

да, я блокирую канвас от доступа к нему из других потоков. можно подробнее о том как делать "по-хорошему"?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо