Delphi - TThread 可以更改主 VCL 线程中变量的值吗?

Delphi - Can a TThread change the value of variable in main VCL thread?

使用:Delphi XE2,Windows VCL Forms 应用程序

TThread 在执行期间能否更改主 VCL 线程中变量的值?

需要更新声明为 TForm class 字段的整数。它将在重载(并重新引入)Create 构造函数方法中作为 var 变量传递给 TThread。

这里面有什么退路吗?

是的,线程可以修改变量。变量不 属于 线程。变量可以属于表单对象或线程对象,但线程对象(即 TThread 或其后代的实例)不同于 OS 执行线程。

对象可以在多个线程中包含 运行 的代码。您的 TThread.Create 方法 运行 在调用它的线程的上下文中,这通常是您的主线程。 Execute 方法,另一方面,运行s 在创建的 OS 线程的上下文中。但是显然,这两种方法都可以访问TThread对象的字段,这样就回答了两个OS线程是否可以访问同一个变量的问题。

不过,您将无法按照您描述的方式访问表单变量。将它作为 var 参数传递给构造函数将允许 constructor 修改它,但正如我上面提到的,构造函数不会 运行 在 new OS线程。要允许新线程访问该变量,您需要存储一个指向它的指针,而不是通过引用传递它。例如:

type
  TSteveThread = class(TThread)
  private
    FVariable: PInteger;
  protected
    procedure Execute; override;
  public
    constructor Create(Variable: PInteger);
  end;

constructor TSteveThread.Create;
begin
  inherited Create(False);
  FVariable := Variable;
end;

procedure TSteveThread.Execute;
begin
  // Access FVariable^ here.
end;

这样创建:

procedure TSteveForm.ButtonClick;
begin
  TSteveThread.Create(@Self.Variable);
end;

另一种方法是传递对表单的引用,然后通过该引用访问表单的字段。例如:

type
  TSteveThread = class(TThread)
  private
    FForm: TSteveForm;
  protected
    procedure Execute; override;
  public
    constructor Create(Form: TSteveForm);
  end;

constructor TSteveThread.Create;
begin
  inherited Create(False);
  FForm := Form;
end;

procedure TSteveThread.Execute;
begin
  // Access FForm.Variable here.
end;

这样创建:

procedure TSteveForm.ButtonClick;
begin
  TSteveThread.Create(Self);
end;

在任何一种情况下,您都需要采取通常的预防措施来控制多个线程对数据的同时访问。最重要的是,两个线程 都可以 访问数据。