Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];

Вниз

Зависает 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 вся ветка

Форум: "WinAPI";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.042 c
2-1220614191
KirillRepin
2008-09-05 15:29
2008.10.12
Буфер обмена


2-1220106974
Alral
2008-08-30 18:36
2008.10.12
Функция Recv и PChar


15-1219210687
ееееееекенитен
2008-08-20 09:38
2008.10.12
разрезать файл


15-1218782666
MBo
2008-08-15 10:44
2008.10.12
Анонимные методы в будущем Тибуроне


3-1207556648
Раиса
2008-04-07 12:24
2008.10.12
Full Join и условие = неверный результат?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский