Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.08.08;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.038 c
14-1090563729
VMcL
2004-07-23 10:22
2004.08.08
Круглые "даты"


4-1088159210
Stager
2004-06-25 14:26
2004.08.08
Всплывающая подсказка из трея


1-1090827398
TUser
2004-07-26 11:36
2004.08.08
Ну вот, проблемы с RichEdit :)


1-1090601696
Jolik
2004-07-23 20:54
2004.08.08
Автоматический перенос слов...


1-1090805019
NumDer32Ok
2004-07-26 05:23
2004.08.08
Base64 алгоритм





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский