Форум: "Основная";
Текущий архив: 2002.04.08;
Скачать: [xml.tar.bz2];
ВнизНити Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c