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

Вниз

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

 
SPeller ©   (2002-03-28 08:59) [0]

Помогите разобраться в нитях. Проблема такова - создаю нить, в которой описываю некоторыю функцию. Функция бесконечна. При её вызове основная программа виснет, как если бы эта функция была в ней. Нить ведь должна выполняться отдель от основной, что я не так делаю? Подскажите..

type
TMyThread = class(TThread)
private
{ Private declarations }
protected
procedure MyProcedure;
public
procedure Execute; override;
end;

implementation

procedure TMyThread.Execute;
begin
Synchronize(MyProcedure);
end;

procedure Tmythread.MyProcedure;
begin
// Бесконечный код
end;

В модуле формы, откуда вызываю:

procedure TfrmMain.FormCreate(Sender: TObject);
begin
thread1:=tmythread.create(true);
end;

procedure TfrmMain.FormDblClick(Sender: TObject);
begin
thread1.Execute;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
thread1.Free;
end;


 
MBo ©   (2002-03-28 09:04) [1]

Sinchronize надо те участки кода, которые обращаются к главному потоку.


 
Виктор Щербаков ©   (2002-03-28 09:06) [2]

Всё правильно. Tmythread.MyProcedure будет выполняться в основном потоке т.к. ты используешь Synchronize.


 
gek   (2002-03-28 09:08) [3]

procedure TfrmMain.FormCreate(Sender: TObject);
begin
thread1:=tmythread.create(true);
thread1.priority:=tpLower;
end;

procedure TfrmMain.FormDblClick(Sender: TObject);
begin
thread1.Resume;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
thread1.suspend;
thread1.Free;
end


 
dymka ©   (2002-03-28 09:09) [4]

процедура переданная в методе Synchronize выполняется в КОНТЕКСТЕ ОСНОВНОГО ПОТОКА ПРИЛОЖЕНИЯ!
Весь код потока должен размещаться в теле Execute, либо вызываться без метода Synchronize!!! Это метод нужен для синхронизации твоего потока и основного потока, например обновление компонентов VCL итп..
Запускать поток нужно конструктором Create, где в качестве параметра передавать False, если поток нужно запустить немедленно, и True, если запустить его ты хочешь позже..
далее.. в теле Execute сделай следующее:
FreeOnTerminate := True; тогда при терминировании потока
он автоматически освободит свои ресурсы...
терминирую поток не вызовом Free, а вызовом метода Terminate,
Внутри потока используй проверку на терминирование - свойство Terminated...


 
dymka ©   (2002-03-28 09:12) [5]

код должен быть такой
type
TMyThread = class(TThread)
private
{ Private declarations }
protected
procedure MyProcedure;
public
procedure Execute; override;
end;

implementation

procedure TMyThread.Execute;
begin
FreeOnTerminate := True;
MyProcedure;
end;

procedure Tmythread.MyProcedure;
begin
// Бесконечный код
...
if Terminated then Break;
...
end;

В модуле формы, откуда вызываю:

procedure TfrmMain.FormCreate(Sender: TObject);
begin
thread1 := tmythread.create(True);
end;

procedure TfrmMain.FormDblClick(Sender: TObject);
begin
thread1.Suspend;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
thread1.Terminate;
end;


 
panov ©   (2002-03-28 09:14) [6]

procedure TMyThread.Execute;
begin while not Terminated do
begin
//здесь делаем полезную работу.
//а также проверяем if Terminated then Break;
//если нужно обновить данные в основном потоке, вызываем метод Synchronize
end;
end;



 
panov ©   (2002-03-28 09:16) [7]

>dymka © (28.03.02 09:12)

procedure Tmythread.MyProcedure;
begin
// Бесконечный код
...
if Terminated then Break; - выполнять надо в Execute;
...
end;



 
dymka ©   (2002-03-28 09:24) [8]

2 panov:
Вовсе нет, т.к. MyProcedure выполняется в потоке, управление будет передано обратно в Execute, где поток и завершит свое выполнение, закончив Execute...


 
SPeller ©   (2002-03-28 09:45) [9]

Спасибо, работает.
Но тут вот возникла другая проблема. Суть полезной работы нити в постоянном рисовании в контекст формы. При попытке перемещения формы изображение начинает хаотично рисоваться по всему экрану (не постоянно хаотично, а передвинул форму - в новом месте), и рисуется по одному кадру, но иногда можно увидеть и движение. Рисуестся то боком на форме, то за формой, то ещё где-нибудь. При этом окна других приложений почти не перерисовываютя, и остаются белые пятна (фон моего изображения белый). Кто знает, что это за баги такие ??


 
dymka ©   (2002-03-28 09:58) [10]

Как рисуешь? На канве??? или еще на чем???
Рисуешь в контексте основного потока? или в своем потоке?


 
gek   (2002-03-28 10:01) [11]

Наверное Canvas.Lock при перемещении
и Canvas.UnLock при прекращении перемещения.
Может поможет.


 
SPeller ©   (2002-03-28 10:05) [12]

Беру непосредственно DC (Canvas.Handle), т.к. рисую через API. Мне надо, чтобы рисование происходило и при перемещении окна.


 
dymka ©   (2002-03-28 10:09) [13]

тогда рисуй лучше на TBitmap или подобном...


 
SPeller ©   (2002-03-28 10:15) [14]

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


 
SPeller ©   (2002-03-28 12:13) [15]

Я нашёл, в чём проблема! ОКАЗЫВАЕТСЯ, рисование в контексте формы и в контексте канвы -- это ДВЕ РАЗНЫЕ вещи !!! Стал рисовать в dc, полученном из GetDC(Form.Handle) и всё стало чику-пуки и никаких косяков! Выходит, что канва формы никак не связана с самой формой, разве что координатами..


 
dymka ©   (2002-03-28 12:28) [16]

:)



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

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

Наверх




Память: 0.51 MB
Время: 0.01 c
14-22791
Alx2
2002-02-22 16:57
2002.04.08
Загадка: непрозрачный квадрат


3-22558
a_a_k
2002-03-15 15:59
2002.04.08
CalcFields


1-22654
solo
2002-03-28 11:32
2002.04.08
Вся работа стоит.


4-22880
ATLANTIDO
2002-02-05 01:12
2002.04.08
Любители хуков и клавиатурных шпионов !


3-22584
KaPaT
2002-03-17 21:07
2002.04.08
Помогите с QReport плииииииз!