【发布时间】:2017-06-04 14:08:48
【问题描述】:
假设我有一个对象,在我的例子中是一个 TThread,我想在一个函数中动态检查它的一个属性,在这个例子中是 TThread.Terminated。
是否有一种干净的方式来传递“属性”,这样我实际上是在传递 getter 函数,因此可以动态检查该属性的值?
更多细节:
我的具体问题是我第一次在 Delphi 中实现线程。我不喜欢标准的 Delphi 线程实现似乎是创建一个自定义线程类来执行您想要线程化的方法。我找到了一个令人满意的解决方案来解决这个烦恼,其中使用委托来定义要执行的方法,然后在创建时将实际方法传递给线程对象,从而更好地分离/封装线程代码和要执行的方法线。详情如下。
但是,我发现上述想法的实现使用 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 的私有成员。” - 不是我推荐的,但是你可以因为吸气剂只读取该字段。请参阅this post 下的讨论。