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

Вниз

потоки   Найти похожие ветки 

 
Hoper   (2003-02-02 16:47) [0]

я запускаю три потока с приоритетом tpIdle, при этом приложение перестаёт реагировать на действия. при одном потоке всё в порядке. Application.ProcessMessages не хотелось бы вставлять, т.к. потоки находятся в компоненте, придётся как-то указывать что за Application.. в общем лень, к тому же интересны сами происходящие процессы (не в программном смысле) .
Вопрос так и должно быть, и почему при одном потоке не возникает проблем?


 
Rouse_   (2003-02-02 16:59) [1]

Вопрос странен сам по себе, ошибка видимо в самих потоках или процедуре их создания.

Ошибка в 17 строке

Желаю успехов


 
Hoper   (2003-02-02 19:42) [2]

то есть, такого быть не должно?


 
mrcat   (2003-02-02 19:46) [3]

т.е. пока не приведете код - ответ вряд ли получите ...


 
Романов Р.В.   (2003-02-02 19:49) [4]

Если в программе нет ошибок то не должно.


 
DiamondShark   (2003-02-03 11:15) [5]


> mrcat © (02.02.03 19:46)
> т.е. пока не приведете код - ответ вряд ли получите ...


А в ответ -- тишина...


 
hoper   (2003-02-04 00:47) [6]

я как-то позабыл о ветке - sorry
дело, видимо, в том что в потоках происходит рисование на канве формы методом Draw


 
Hoper   (2003-02-05 08:52) [7]

я прав?


 
Anatoly Podgoretsky   (2003-02-05 09:02) [8]

Ну тебе же сказали "Ошибка в 17 строке"


 
Hoper   (2003-02-06 02:58) [9]

строка №17: Bmp: TBitmap; =) imho, здесь как раз всё правильно =)
не вдаваясь в подробности выводимой графики и специфичных свойств компонента, код таков:

type
TDrThread = class(TThread)
private
OutCanvas: TCanvas;
Bmp: TBitmap;
public
constructor Create;
destructor Destroy; override;
protected
procedure DoIt;
procedure Execute; override;
end;

TDrawThread = class(TComponent)
private
DrThread: TDrThread;
FPriority: TThreadPriority;
FCanvas: TCanvas;
protected
procedure SetCanvas(const Value: TCanvas);
public
property Canvas: TCanvas read FCanvas write SetCanvas;
constructor Create(AOwner: TComponent); override;
procedure Start;
procedure Stop;
published
end;

implementation

constructor TDrThread.Create;
begin
inherited Create(true);
end;

procedure TDrThread.Execute;
begin
while not Terminated do
Synchronize(DoIt);
end;

procedure TDrThread.DoIt;
begin
if Suspended then exit;
ChangeBmp(Bmp);
Canvas.Draw(0,0,Bmp);
end;

constructor TDrawThread.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
DrThread:=TDrThread.Create;
Priority:=tpIdle;
end;

procedure TDrawThread.Start;
begin
if Canvas=nil then exit;
if not DrThread.Suspended then exit;
with DrThread do
begin
OutCanvas:=Canvas;
end;
DrThread.Priority:=FPriority;
DrThread.Resume;
end;


 
Юрий Зотов   (2003-02-06 06:15) [10]

procedure TDrThread.Execute;
begin
while not Terminated do Synchronize(DoIt);
end;

Какой смысл в ТАКОМ потоке? Абсолютно никакого. Метод DoIt все равно выполняется в главном потоке и в результате главный поток бесконечно рисует иконку без всяких ProcessMessages. А мы удивляемся, что приложение ни на что не реагирует.

И второе - посмотрите TCanvas.Lock. В частности, там сказано:
"Any thread that does not lock the canvas before using it will introduce potential bugs.".


 
Hoper   (2003-02-06 11:45) [11]

2 Юрий Зотов
2. До методов Lock-Unlock в хелпе действительно никогда не добирался. Возьму на вооружение.
1. Подскажите тогда, pls, как в потоке выводить на канву постоянно обновляемую битовую матрицу.


 
Юрий Зотов   (2003-02-06 12:05) [12]

А зачем постоянно рисовать?

Прорисовку вставляем в какой-нибудь OnPaint (WM_PAINT и пр.). А после обновления вызываем какой-нибудь Invalidate.

Вот и все. Просто, как веник. И никаких потоков, и лишнюю работу не делаем.

А вот это:
while not Terminated do <рисовать>
Вы представляете, к чему это приведет? А с Idle возникнет проблема перерисовки при перекрытии окон.


 
Hoper   (2003-02-06 23:12) [13]

с одним потоком проблем не возникало..
>И никаких потоков
а как тогда выполнять непрерывный вывод изменнённой картинки, просто на таймер стоит повесить?


 
Юрий Зотов   (2003-02-07 00:08) [14]

Зачем нужен обязательно непрерывный вывод? Вам машину не жалко?

Рисовать нужно только тогда, когда это действительно нужно. А это только 2 случая.

1. Когда изменилась картинка. Для этого после ее изменения вызываем метод Invalidate или что-то ему подобное. То есть, запрашиваем перерисовку.

2. Когда система посылает окну сообщение о том, что оно должно себя перерисовать (например, сдвинулось перекрывающее окно). Это сообщение - WM_PAINT. Для формы и для некоторых контролов ему соответствует событие OnPaint или метод Paint, а для других можно написать обработчик самого сообщения. Вот здесь и пишем код, выполняющий само рисование.


 
Hoper   (2003-02-07 01:59) [15]

мне нужно, чтобы при выполнении трудоёмких (для компьютера) вычислений и проверок выводилась красивая вращающаяся картинка (как весьма далёкий пример могу привести заставку при загрузке винды), так что у меня третий случай.


 
Hoper   (2003-02-07 02:02) [16]

то есть у я рисую статичную картинку, из неё беру часть, эту часть мне и надо вывести, потом другую и т.д. при этом нужно, как я и писал, заниматься более нужными, но невидимыми изменениями. progress bar просто надоел


 
Ей-богу   (2003-02-07 04:24) [17]

впомнил "бравого солдата Швейка" и высказывание оттуда по поводу эстетов и гомосексуалистов. Искренне прошу не принимать на свой счет сие мое высказывание. Но, имхо, Ваши проблемы Вы создаете себе сами. Для индикации "времязатратных" процессов прекрасно служат ProgressBar и статусные строки. Для, сам не пойму для чего, но для чего то близкого Вашей задаче служат скринсейверы. Но если уж очень хочется для индикации длительного процесса рисовать некие картинки, рисуйте. Но обратите внимание, что отрисовка картинки происходит в основном потоке. Может быть лучше перенести в другой поток Вашу процедуру с "трудоёмких (для компьютера) вычислений и проверок"?


 
Юрий Зотов   (2003-02-07 09:25) [18]

Все сказал Ей-богу (07.02.03 04:24), остается только повторить.

Третьго случая не бывает, если только его не придумывать специально (что Вы и пытаетесь сделать). Рисуйте по нормальной схеме, в основном потоке (см. выше), а вычисления перенесите в дополнительный поток.


 
Hoper   (2003-02-07 20:27) [19]

2 Ей-богу
как чётко Вы меня поняли: выдалось свободное время и я решил попрактиковаться в том, чем никогда не занимался - так, на всякий будущий случай
2 Юрий Зотов
конечно, резоннее было бы вычисления выполнять в потоке, а не рисование, но см. выше
эксперимент закончен, результат - фиаско..



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

Форум: "Основная";
Текущий архив: 2003.02.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.01 c
7-53315
ewgeny
2002-12-15 10:38
2003.02.17
Service + приложение


14-53251
Adolf
2003-01-31 22:22
2003.02.17
XP


1-52861
Trix
2003-02-07 17:03
2003.02.17
MATH


14-53172
NetBreaker666
2003-02-02 17:38
2003.02.17
Ну, что, меня здесь еще кто-нибудь помнит ?


3-52728
Calm
2003-01-30 11:17
2003.02.17
Не работает select * from MyTable!





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский