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

Вниз

Многократный запуск собственного потока   Найти похожие ветки 

 
DeScriptor   (2004-07-23 21:27) [0]

Есть у меня TThread, в котором код Execute выглядит следующим образом:

procedure TResProcessing.Execute();
begin
 case JobID of
   RP_SCAN: ScanResFile();
   RP_EXTR: ExtractFiles();
   RP_PACK: PackFiles();
 end;
end;


Оказалось, что если я меняю JobID, и снова вызываю метод Resume, ничего больше не происходит (делаю я это после того, как сам поток сообщит основному коду, что он отработал - для этого я целую систему процедур придумал). Я пытался делать Destroy или Free, в той процедуре в главном коде, которую он вызывает, когда сообщает что все сделано, но это приводит к полным висюкам (я вообще не знаю, как убить поток после того, как он сделал свое дело). Я пытался ставить свойство FreeOnTerminate:=true, но это никаких результатов не дало.
А мне нужно, чтобы можно было хоть до посинения нажимать кнопку в главной форме, что приводило бы к выполнению потоком каких-то задач, но с последующей возможностью выполнения им же еще каких-нибудь задач путем нажатия той же самой кнопки. Чего с этим делать - не знаю. И вообще не знаю, убивается ли он при завершении программы. Хелп прочитал на эту тему вдоль и поперек, но ничего толкового так и не достиг.
Создавать для каждого набора задач отдельные экземпляры этого класса, или создавать три разных класса для трех разных наборов задач очень накладно.
А отказаться от использования отдельного потока я не могу, т.к. процессы, которые в нем выполняются, могут затянуться надолго, при этом может возникнуть необходимость прервать их.


 
Mim1 ©   (2004-07-24 08:01) [1]

Я предлагаю вам такое решение


var
 ThreadWorking : boolean = false;

TResProcessing = class(TThread)
Public
 JobID:integer;
...
end;

procedure TResProcessing.SetEndWork;
begin
 ThreadWorking := false;
end;


> procedure TResProcessing.Execute();
> begin
  while not terminated do
 begin
>  case JobID of
>    RP_SCAN: ScanResFile();
>    RP_EXTR: ExtractFiles();
>    RP_PACK: PackFiles();
>  end;
  sincronize(SetEndWork);
  suspend;
 end;
> end;


И в основном потоке
if not (ThreadWorking) then
 begin
   ThreadWorking := true;
   ResProcessing.jobid :=  100;
   ResProcessing.resume;
 end


 
Polevi ©   (2004-07-24 14:03) [2]

а еще лучше организовать в потоке цикл выборки сообщений и управлять им через PostThreadMessage


 
DeScriptor   (2004-07-24 14:37) [3]

А можно поподробнее про сообщения и их выборку?


 
DeScriptor   (2004-07-24 14:41) [4]

2Mim1 Я пробовал так, как вы советуете - ничего не получается! =( Результат все тот же - полное отсутствие оного.


 
Palladin ©   (2004-07-24 15:23) [5]

А еще лучше организовать три разновидности потока на эти разные действия.


 
Mim1 ©   (2004-07-24 15:43) [6]


> DeScriptor   (23.07.04 21:27)

А у меня работает

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TMimThread = class(TThread)
 private
   procedure SetEndWork;
 protected
   procedure Execute; override;
 public
   beepfreq : integer;
 published

 end;

 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   { Private declarations }
   MimThread : TMimThread;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

var
ThreadWorking : boolean = false;

procedure TForm1.Button1Click(Sender: TObject);
begin
 if not (ThreadWorking) then
  begin
    ThreadWorking := true;
    MimThread.beepfreq := -1;
    MimThread.resume;
  end

end;

{ TMimThread }

procedure TMimThread.Execute;
begin
while not terminated do
begin
  MessageBeep(beepfreq);
//   windows.MessageBox(0,"1","2",0);
  Synchronize(SetEndWork);
  suspend;
end;
end;

procedure TMimThread.SetEndWork;
begin
ThreadWorking := false;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 MimThread := TMimThread.Create(true);
 MimThread.FreeOnTerminate := true;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 MimThread.terminate;
end;

end.


 
Бином Ньютоныч   (2004-07-24 16:19) [7]

>Palladin ©   (24.07.04 15:23) [5]

Сомневаюсь, что это будет лучше. Дорогая операция - создание потока, если, конечно, это имеет значение. Имхо, >Polevi ©   (24.07.04 14:03) [2] оптимально, хотя и не обязательно это должны быть сообщения.


 
Palladin ©   (2004-07-24 16:43) [8]

Что есть лучше? Лучшее решение для исполнения? Практически нет, для реализации? Да.


 
Бином Ньютоныч   (2004-07-24 16:48) [9]

>Palladin ©   (24.07.04 16:43) [8]

Ни-и-и-и-че не понял:) Можно по-проще, для особо одаренных?


 
Palladin ©   (2004-07-24 16:53) [10]

:)
А так понятно?
Разделяй и властвуй.


 
Бином Ньютоныч   (2004-07-24 17:22) [11]

:)))
Теперь въехал:)


 
DeScriptor   (2004-07-24 20:46) [12]

Ситуевину я разрулил, примерно как предлагал Mim1:
procedure TResProcessing.Execute();
begin
 While not
Terminated do
   if not
JobComplete then case JobID of
       RP_SCAN: ScanResFile();
       RP_EXTR: ExtractFiles();
       RP_PACK: PackFiles();
     end;
end;


JobComplete устанавливается в true, когда надо, чтобы поток поработал, как только он заканчивает работу, он устанавливает JobComplete в false, после чего синхронизацией вызывает процедуру из главного потока, которая выполняет дальнейшие действия.


 
Mim1 ©   (2004-07-24 21:10) [13]


> [12] DeScriptor   (24.07.04 20:46)

Без suspend поток не будет останавливаться а ьудет вертется вхолостую расходуя ресурсы процессора.

А почему не использовать приведенный пример в полном соответствии один к одному.


 
Polevi ©   (2004-07-24 22:16) [14]

procedure TT.Execute;
var
 msg:TMsg;
begin
 while not Terminated do
 begin
   GetMessage(msg,0,0,0);
   case msg.message of
     RP_SCAN: ScanResFile();
     RP_EXTR: ExtractFiles();
     RP_PACK: PackFiles();
     RP_QUIT: Terminate;
   end;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 PostThreadMessage(T.ThreadId, RP_QUIT, 0, 0);
 //последнии 2 параметра будут доступны через msg.wParam и msg.lParam в теле поточной ф-ии
 //можете пользоваться
end;


 
Serge_   (2004-07-25 00:48) [15]

Дак что надо-то, я ваще не понял..
Остановить поток(нить)?
И запустить новый???
али как?

thread.terminate;

Но поток не остановиться сразу, этот метод просто установит флаг Terminated вот его то ты и должен проверять как в методе Execute
так и в процедурах которые вызываются из Execute...
поток завершиться по выходе из Execute...
Если нужно быстрее и менее хлопотно тоды делай TerminateThread(Thread.Handle); твой поток не узнает что ты его залупил...


 
Polevi ©   (2004-07-25 10:42) [16]

> [15] Serge_   (25.07.04 00:48)
иногда лучше жевать


 
DiamondShark ©   (2004-07-25 15:48) [17]


> Polevi ©   (24.07.04 22:16) [14]

Такой поток не завершится, пока не отработает какой-нибудь месадж.

procedure TT.Execute;
var
msg:TMsg;
begin
while integer(GetMessage(msg,0,0,0)) > 0 do
  case msg.message of
    RP_SCAN: ScanResFile();
    RP_EXTR: ExtractFiles();
    RP_PACK: PackFiles();
    RP_QUIT: Terminate;
  end;
end;

А для завершения послать WM_QUIT


 
Бином Ньютоныч   (2004-07-25 16:36) [18]

>DiamondShark ©   (25.07.04 15:48) [17]
>Такой поток не завершится, пока не отработает какой-нибудь месадж.

Ну дык RP_QUIT на то и вставлен, а?


 
DiamondShark ©   (2004-07-25 16:41) [19]

А, ну да ;)
А чем он лучше WM_QUIT-а?


 
Бином Ньютоныч   (2004-07-25 17:00) [20]

Да ничем собсно...так, к слову пришлось:))



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

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

Наверх




Память: 0.52 MB
Время: 0.028 c
6-1086678438
leonidus
2004-06-08 11:07
2004.08.08
Вопрос по TWebBrowser


3-1089859136
CHTR
2004-07-15 06:38
2004.08.08
Где найти инфу по работе с Access отчетами


14-1090409593
ййй
2004-07-21 15:33
2004.08.08
А вот...


3-1089860328
Ozone
2004-07-15 06:58
2004.08.08
Непонятки с запросом


1-1090788416
Юрий Ж.
2004-07-26 00:46
2004.08.08
Проблема с копированием в ClipBoard!