Спасибо.
Кажется почти разобрался
Код:
1 2 3 4 5 6 | .....
For I := Low(FThreads) To High(FThreads) Do
Begin
FThreads[i].Terminate;
FThreads[i].WaitFor;
End ;
|
У TThread есть некое Boolean свойство, при запуске потока оно установлено в False, в обычном случае по завершении Execute оно устанавливается в True и поток самовыпиливается (при FreeOnTerminate:=True разумеется) ... во! нашел
Код:
1 2 3 4 5 6 | procedure TThread . Terminate;
begin
...
FTerminated := True ;
....
end ;
|
В нашем случае мы зацикливаем Execute с помощью Terminated на проверку очереди заданий, а с помощью FThreads[i].Terminate даем возможность выскочить из цикла и завершить Execute. WaitFor - ждем от потока сообщения: "Я кончил, прощайте". Вроде так.
Только надо придумать как передавать задания не строкой, а ну скажем record, или в качестве задания формировать строку с разделителями, а для потока наколхозить функцию, которая эту строку будет разбирать.
...upd...
Вроде бы остановился на варианте запихать в TList record-ы, а теперь меня терзают смутные сомнения, не ересь ли я написал
пишу по памяти, сам проект остался на работе, в ноуте
Код:
1 2 3 4 5 6 7 | unit MyThread;
...
type
TSomeData = record
n1, n2, n3: Integer ;
m1, m2: Byte ;
....
|
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | unit Unit1
...
procedur AddToQueue;
var SomeData: TSomeData;
i: Integer ;
begin
for i:= 0 to someNamber do
begin
SomeData . n1:=
SomeData . n2:=
....
SomeData . m2:=
List . Add(SomeData);
end ;
end ;
|
но TList это список указателей, а я ведь не создаю новый экземпляр TSomeData т.е. я добавляю в лист указатель на одну и ту же переменную.
Но даже если этот вопрос будет решен остается другой
Изначально планировал наследовать от TThread, скажем так прототип, в который инкапсулирую IdHTTP и прочее, а от него создаю наследников под разные задачи с разными, соответственно наборами данных т.е. с разными record-ами (TSomeData1 = record, TSomeData2 = record и т.д.)
В новом варианте усмотрел следующую возможность - ограничится одним наследником, а разные задачи раскидать по разным процедурам
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | type
TWorkerThread = class (TThread)
......
FMode: TMode
......
end ;
..........
implementation
procedure TWorkerThread . Execute;
var
S : String ;
begin
While not Terminated Do
Begin
S := '' ;
cs . Enter;
Try
If FList . Count > 0 Then
Begin
S := FList[ 0 ];
FList . Delete( 0 );
End ;
Finally
cs . Leave;
End ;
If S <> ''
Then
Case of FMode
mdCheck: ProcessCheck(S);
mdLoad: ProcessLoad(S);
end ;
Else Sleep( 1000 )
End ;
end ;
|
Вернее так - у меня есть FMode и какой тип записи будет я знаю, но это будет уже в RunTime, а объявить переменную нужно сразу.
Я так себе представляю - это нужно из List-а вытащить указатель, независимо от того на какой тип записи он указывает, а в соответствующей процедуре будет объявлена переменная нужного типа и по указателю получаю нужный record.