Скажем, у меня есть объект, в моем случае TThread, и я хочу динамически проверять одно из его свойств в функции, в этом случае TThread.Terminated.Как передать динамическое свойство в качестве параметра функции?
Есть ли чистый способ передать свойство, так что я фактически передаю функцию getter и могу ли вы проверить динамическое значение этого свойства?
Подробнее:
Мой конкретный вопрос в том, что я реализую многопоточности в Delphi впервые. Я не являюсь поклонником того факта, что стандартная реализация Delphi Threading состоит в создании собственного класса потоков для выполнения метода, который вы хотите использовать. Я нашел удовлетворительное решение этой досады, когда кто-то использует делегат для определения метода для выполнения, а затем передает фактический метод в объект потока при создании, что позволяет лучше разделить/инкапсулировать код потока и метод, который будет выполняться с помощью нить. Подробности ниже.
Однако реализация вышеуказанной идеи, которую я нашел, использует TThread.Suspend, чтобы разрешить досрочное завершение выполняемого метода. Документы Delphi отмечают TThread.Suspend как устаревшие, а вместо этого предлагают, чтобы длинные методы должны проверять свойство Terminated, чтобы разрешить досрочное расторжение при запросе родительского потока. Таким образом, мне нужен способ передать ссылку на TThread.Terminated на метод, который он выполняет, чтобы этот метод мог реализовать свое раннее завершение.
Я не могу передать свойство по ссылке, используя синтаксис var. Я не могу передать базовое поле FTerminated по ссылке, так как это частный член TThread. Я знаю, что могу просто передать ссылку на объект TThread в этот метод, но этот тип циклических ссылок кажется халатным способом обойти проблему.
Итак, есть ли «принятый» способ динамически передать свойство, или я придерживаюсь своего текущего метода?
Текущий код: интерфейс
uses
Windows, Messages, Classes, Forms;
type
// Method Thread Will Execute. Acts on Data. Runs in RunningThread.
// (Reference to RunningThread is past so method can check runningthread.terminated
// to allow long running methods to terminate early when parent thread requests it)
TThreadMethod = procedure (Data: pointer; RunningThread: TThread) of object;
//A Simple Thread Which Excecutes a Method on Some Data
TSimpleThread = class(TThread)
protected
Method: TThreadMethod;
Data: pointer;
procedure Execute; override;
public
constructor Create(Method: TThreadMethod; Data: pointer; CreateSuspended: boolean); overload;
end;
implementation
// SimpleThread
constructor TSimpleThread.Create(Method: TThreadMethod;
Data: pointer;
CreateSuspended: boolean);
begin
Self.Method := Method;
Self.Data := Data;
inherited Create(CreateSuspended);
Self.FreeOnTerminate := True;
end;
procedure TSimpleThread.Execute();
begin
Self.Method(Data, Self);
end;
Попросите класс нить реализовать интерфейс, который вы передаете в свой метод выполнения потока. –
- * «Я не могу передать основное поле FTerminated по ссылке, поскольку он является частным членом TThread». * - Не то, что я рекомендую, но вы можете, поскольку геттер только читает поле. См. Обсуждение в разделе [этот пост] (http://stackoverflow.com/questions/25666626/delphi-change-main-form-while-application-is-running). –