Текущий архив: 2003.02.17;
Скачать: CL | DM;
Внизпотоки Найти похожие ветки
← →
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;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.011 c