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

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

потоки [D5]


Hoper ©   (2003-02-02 16:47:00) 

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


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

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


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

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

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


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

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


Hoper   (2003-02-07 02:02:00) [4]

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


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

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


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

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

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

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

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


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

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


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

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

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

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

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


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

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


Юрий Зотов   (2003-02-06 06:15:00) [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 02:58:00) [11]

строка №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;


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

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


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

я прав?


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

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


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


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


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


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

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


mrcat   (2003-02-02 19:46:00) [17]

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


Hoper   (2003-02-02 19:42:00) [18]

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


Rouse_   (2003-02-02 16:59:00) [19]

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

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

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


Наверх

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