使用:Delphi XE2,Windows VCL Forms应用程序
TThread在执行期间是否可以更改主VCL线程中变量的值?
需要更新一个被声明为TForm类的字段的Integer.它将作为重载(并重新引入)Create构造函数方法中的var变量传递给TThread.
这有什么后盾吗?
Rob*_*edy 10
是的,线程可以修改变量.变量不属于线程.变量可以属于表单或线程对象,但是线程对象(即,TThread其后代的实例或其后代)与OS执行线程不同.
对象可以具有在多个线程中运行的代码.您的TThread.Create方法在调用它的线程的上下文中运行,这通常是您的主线程.Execute另一方面,该方法在创建的OS线程的上下文中运行.但很明显,这两种方法都可以访问TThread对象的字段,因此可以回答两个OS线程是否可以访问同一个变量的问题.
但是,您将无法以您描述的方式访问表单变量.将它作为var参数传递给构造函数将允许构造函数修改它,但正如我上面提到的,构造函数不会在新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;
Run Code Online (Sandbox Code Playgroud)
像这样创建它:
procedure TSteveForm.ButtonClick;
begin
TSteveThread.Create(@Self.Variable);
end;
Run Code Online (Sandbox Code Playgroud)
另一种方法是将引用传递给表单,然后通过该引用访问表单的字段.例如:
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;
Run Code Online (Sandbox Code Playgroud)
像这样创建它:
procedure TSteveForm.ButtonClick;
begin
TSteveThread.Create(Self);
end;
Run Code Online (Sandbox Code Playgroud)
在任何一种情况下,您都需要采取通常的预防措施来控制多个线程同时访问数据.底线是两个线程都可以访问数据.