Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.10.12;
Скачать: CL | DM;

Вниз

Зависает API функция EnterCriticalSection   Найти похожие ветки 

 
Unknown user ©   (2007-12-12 17:37) [0]

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

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

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


 
Eraser ©   (2007-12-12 17:43) [1]


> Unknown user ©   (12.12.07 17:37) 

перед прорисовкой на канвасе нужно вызывать Canvas.Lock, после отрисовки - Canvas.Unlock. И это еще не обезопасит полностью от проблем с потокобезопасностью..
по-хорошему надо перехватывать сообщение WM_SYSCOLORCHANGE.


 
Unknown user ©   (2007-12-12 18:14) [2]

> Eraser

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


 
Unknown user ©   (2007-12-13 10:12) [3]

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


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


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


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

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


 
tesseract ©   (2007-12-13 10:24) [5]


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


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


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


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


 
Unknown user ©   (2007-12-13 10:44) [7]

> Сергей М. & tesseract

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

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


 
Unknown user ©   (2007-12-13 10:46) [8]


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


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


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


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


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

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


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

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


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


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

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


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


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


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

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

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


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


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


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

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

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


 
Eraser ©   (2007-12-13 11:12) [14]


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


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

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

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


 
Unknown user ©   (2007-12-13 12:34) [15]


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


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

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


Synchronize(Draw);

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



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


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

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


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


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


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


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


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


 
Unknown user ©   (2007-12-13 12:53) [17]


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


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


 
Eraser ©   (2007-12-13 13:17) [18]


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


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

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


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


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


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


 
DiamondShark ©   (2007-12-13 13:26) [20]


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

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

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

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


 
tesseract ©   (2007-12-13 16:36) [21]


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


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


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


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



Страницы: 1 вся ветка

Текущий архив: 2008.10.12;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.023 c
15-1219386429
zdm
2008-08-22 10:27
2008.10.12
Формат отображения вещественных данных


15-1219373522
Slider007
2008-08-22 06:52
2008.10.12
С днем рождения ! 22 августа 2008 пятница


2-1220529187
KirillRepin
2008-09-04 15:53
2008.10.12
помогите с DBComboBox


2-1220458416
New_ser
2008-09-03 20:13
2008.10.12
Как создать БД с "координатами"?


3-1208021181
koss__
2008-04-12 21:26
2008.10.12
Out Of Memory в датасете