Показать сообщение отдельно
  #9  
Старый 20.12.2018, 09:31
Аватар для Помидоркин
Помидоркин Помидоркин вне форума
Начинающий
 
Регистрация: 07.10.2012
Адрес: Дедовск
Сообщения: 110
Версия Delphi: Rio 10.3
Репутация: 10
По умолчанию

Спасибо.
Кажется почти разобрался
Код:
.....
  For I := Low(FThreads) To High(FThreads) Do
    Begin
      FThreads[i].Terminate;
      FThreads[i].WaitFor;
    End;
У TThread есть некое Boolean свойство, при запуске потока оно установлено в False, в обычном случае по завершении Execute оно устанавливается в True и поток самовыпиливается (при FreeOnTerminate:=True разумеется) ... во! нашел
Код:
procedure TThread.Terminate;
begin
...
  FTerminated := True;
....
end;
В нашем случае мы зацикливаем Execute с помощью Terminated на проверку очереди заданий, а с помощью FThreads[i].Terminate даем возможность выскочить из цикла и завершить Execute. WaitFor - ждем от потока сообщения: "Я кончил, прощайте". Вроде так.

Только надо придумать как передавать задания не строкой, а ну скажем record, или в качестве задания формировать строку с разделителями, а для потока наколхозить функцию, которая эту строку будет разбирать.

...upd...
Вроде бы остановился на варианте запихать в TList record-ы, а теперь меня терзают смутные сомнения, не ересь ли я написал
пишу по памяти, сам проект остался на работе, в ноуте
Код:
unit MyThread;
...
type
 TSomeData = record
   n1, n2, n3: Integer;
   m1, m2: Byte;
....
Код:
unit Unit1
...
procedur AddToQueue;
var SomeData: TSomeData;
      i: Integer;
begin
 for i:= 0 to someNamber do
 begin
  SomeData.n1:= //bla bla bla
  SomeData.n2:= //bla bla bla
  ....
  SomeData.m2:= //bla bla bla
  List.Add(SomeData);
 end;
end;
но TList это список указателей, а я ведь не создаю новый экземпляр TSomeData т.е. я добавляю в лист указатель на одну и ту же переменную.
Но даже если этот вопрос будет решен остается другой
Изначально планировал наследовать от TThread, скажем так прототип, в который инкапсулирую IdHTTP и прочее, а от него создаю наследников под разные задачи с разными, соответственно наборами данных т.е. с разными record-ами (TSomeData1 = record, TSomeData2 = record и т.д.)
В новом варианте усмотрел следующую возможность - ограничится одним наследником, а разные задачи раскидать по разным процедурам
Код:
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.
Ответить с цитированием