При вызове TThread.Queue не возвращает значение из потока в основной
С главной формы приложения создается вторичная форма:
var
modal: TForm2;
begin
modal := Tform2.create(application);
try
modal.showmodal;
finally
modal.free
end;
В ней по нажатию на кнопку создается поток, который должен будет обращаться к базе и работать с данными. для отображения на интерфейсе пользователю из потока должны передаваться текстовые значения статусов работы.
реализовано следующим образом:
TForm2 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
MyThread: TMyThread;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
FreeAndNil(MyThread);
MyThread := TMyThread.Create(False);
end;
procedure TMyThread.Execute;
var
obj: TUpdatingAddressData;
begin
obj := TUpdatingAddressData.Create;
LogEvent('Изменение структуры таблиц');
obj.AlterTable;
LogEvent('Завершено');
obj.Free;
end;
где:
procedure TMyThread.LogEvent(EventText: string);
begin
TThread.Queue(nil,
procedure
begin
Form2.Memo1.Lines.Add(EventText);
Form2.Label1.Caption := EventText;
end);
end;
Данная реализация не обновляет Caption и не добавляет в Memo значение. Однако если реализовать тот же код в главной форме приложения, обновление текста происходить будет.
Чем отличаются главная форма приложения и вторичная для создаваемых потоков в данном случае? Как корректно реализовать передачу строк из потока в форму?
Ответы (1 шт):
Передача данных из потока в его конце с помощью Queue - не очень хорошая идея.
Дело в том, что поток тут же уничтожается, а поставленные в очередь события стираются (RemoveQueuedEvents(Self) в деструкторе TThread).
Поэтому здесь лучше сделать Synchronize (который ждёт исполнения процедур) или передавать данные в OnTerminate (который на самом деле обёрнут в тот же Synchronize).
Если уже много чего наверчено с Queue, то обходной маневр - вызвать Synchronize в конце, вся очередь вытеснится