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

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

Как грамотно остановить, убить поток [D7, 95/98, ME, NT4, 2000, XP, 2003]


СержК ©   (2006-01-27 11:46:00) 

Народ подскажите.

Изучаю потоки. Создал поток. В этом потоке запускаю огромный цикл с выводом информации о работе потока(цикла)  на рабочую форму.

До тех пор пока работа цикла НЕ ЗАВЕРШЕНА, из главной формы пытаюсь остановить работу потока следующим образом:

procedure TForm1.Button2Click(Sender: TObject);
begin
MyThread.Suspended:=true;
MyThread.Terminate;
end;  - останавливается вроде все нормально

Но если я нажимаю кнопку Form1.Button2Click уже после как поток отработал, вываливается ошибка - "Отказано в доступе..."

Подскажите что я делаю не так?

Попутно вопросы:
1) Как правильно остановить поток
2) Как убить поток вообще


SergP   (2006-01-28 03:19:00) [1]


> procedure TMyThread.Execute;
> var i:integer;
> begin
> for i:=1 to 10000 do
>  begin
>  Form1.RichEdit1.Lines.Add(IntToStr(i));
>  end;
> end;


И кстати, тебе уже писали что так делать не надо... Может работать, но могут быть страшные глюки


SergP   (2006-01-28 03:15:00) [2]

Либо сюда:

procedure TForm1.LaunchYourThread(const ADirectoryName:
String);
begin
MyThread := TMyThread.Create(True, ADirectoryName);
MyThread.FreeOnTerminate:=True;
MyThread.Resume;
end;


либо сюда:


constructor TMyThread.Create(CreateSuspennded: boolean;
const ADirectoryName: String);
begin
inherited Create(CreateSuspennded);
FDirectoryName := ADirectoryName;
FreeOnTerminate:=True;
end;


ИМХО так...


СержК   (2006-01-27 15:24:00) [3]

Вот весь код.
Куда нужно вставить: FreeOnTerminate:=True

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Clear;
RichEdit1.Clear;
//**************************

LaunchYourThread('хххххххххх');

//***********************
end;

procedure TForm1.LaunchYourThread(const ADirectoryName: String);
begin
MyThread := TMyThread.Create(True, ADirectoryName);
MyThread.Resume;
end;

//**********************************************
//**********************************************

САМ ПОТОК

{ TMyThread }

constructor TMyThread.Create(CreateSuspennded: boolean;
 const ADirectoryName: String);
begin
inherited Create(CreateSuspennded);
FDirectoryName := ADirectoryName;
end;

procedure TMyThread.Execute;
var i:integer;
begin
for i:=1 to 10000 do
 begin
 Form1.RichEdit1.Lines.Add(IntToStr(i));
 end;
end;


sniknik   (2006-01-27 15:06:00) [4]

написано правильно... может не в том месте, не в то время? :)


СержК   (2006-01-27 14:52:00) [5]

Пардон, но

FreeOnTerminate:=True  почемуто не понимает.

Опять тот же Undeclared identifier: 'FreeOnTerminate'


Johnmen   (2006-01-27 14:29:00) [6]

Сам собой, если в процедуре создания укажешь FreeOnTerminate:=True


СержК   (2006-01-27 14:22:00) [7]

ok - Все заработало!!!

Торможу, убиваю поток - вроде все работает, но возник еще вопросик:
Когда мой поток отработал ("огромный цикл") его(поток) убивать нужно, или он сам собой?


sniknik   (2006-01-27 14:03:00) [8]

ошибся в написании...;( надо Te rminated но ты сам то написал правильно, и неужели недогадался?


Johnmen   (2006-01-27 14:02:00) [9]

Tetminated <> Terminated


СержК   (2006-01-27 13:59:00) [10]

Если я правильно понял, то сделал следующее.

procedure TMyThread.Execute;
var i:integer;
begin
For i:=1 to 100000 do
  begin

  if Tetminated then Exit;

  Form1.RichEdit1.Lines.Add('Текущая строка - ' + IntToStr(i));
  end;
end;

Но при компиляции выдает ошибку: Undeclared identifier: 'Terminated'

???


sniknik   (2006-01-27 13:39:00) [11]

к примеру вставив в цикл if Tetminated then Exit;

p.s. обращатся из потока к обьектам VCL нельзя... (и вообще любым если используются максимум 2мя потоками)


СержК   (2006-01-27 13:17:00) [12]

Что-то не получается.
Привожу основную процедуру с "огромным циклом". Где и как я должен сделать - проверку на завершение???

procedure TMyThread.Execute;
var i:integer;
begin
For i:=1 to 100000 do
   begin
   Form1.RichEdit1.Lines.Add('Текущая строка - ' + IntToStr(i));
   end;
end;


sniknik   (2006-01-27 12:02:00) [13]

MyThread.Suspended:=true;
приостановил поток

MyThread.Terminate;
дал ему команду завершится

которая не выполнится т.к. "огромный цикл" есть а проверки на завершение наверняка нет (не написано значит нет), и потом т.к. он приостановлен то команды в нем не выполняются... до resume.

> Подскажите что я делаю не так?
см. up.


Наверх

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