读书人

多线程怎么访问外部变量

发布时间: 2013-12-13 00:50:19 作者: rapoo

多线程如何访问外部变量
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
type
TForm1 = class(TForm)

Button1: TButton;
ProgressBar1: TProgressBar;
Label1: TLabel;
procedure Button1Click(Sender: TObject);

private
{ Private declarations }

public
{ Public declarations }
pubstr:string;
end;

var
Form1: TForm1;

{$R *.dfm}
implementation

type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;

procedure TMyThread.Execute;
begin
inherited;
FreeOnTerminate := True; {这可以让线程执行完毕后随即释放}
form1.pubstr:='test';
end;

procedure TForm1.Button1Click(Sender: TObject);
var tmpstr:string;
begin
pubstr:='';
TMyThread.Create(False);
label1.caption:=pubstr;
end;

end.

上面是代码。
问题是:程序执行后,pubstr的值为空,是什么原因造成的??
    按理说程序执行后pubstr的值应该是 test
先谢谢各位!!

[解决办法]


unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
ProgressBar1: TProgressBar;

procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure ThreadTerminate(Sender: TObject); // 加个回调函数
public
{ Public declarations }
pubstr: string;
end;

var
Form1: TForm1;

{$R *.dfm}
implementation

type
TMyThread = class(TThread)
protected
procedure Execute; override;
public
form: TForm1; // 保存TForm1的引用
end;

procedure TMyThread.Execute;
begin
inherited;
FreeOnTerminate := True; {这可以让线程执行完毕后随即释放}
form.pubstr := 'test';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
myThread: TMyThread;
begin
pubstr := '';
myThread := TMyThread.Create(True);
myThread.form := Self;
myThread.OnTerminate := ThreadTerminate; // 当线程指向完毕后指向回调函数
myThread.Resume;

end;

// 线程执行完毕后的调回函数
procedure TForm1.ThreadTerminate(Sender: TObject);
begin
Label1.Caption := pubstr;
end;

end.


[解决办法]
另一种方式

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
ProgressBar1: TProgressBar;

procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
pubstr: string;
end;

var
Form1: TForm1;

{$R *.dfm}
implementation

type
TMyThread = class(TThread)
protected
procedure Execute; override;
procedure SetFormControlCaption;


public
form: TForm1; // 保存TForm1的引用
end;

// 设置form1的label1,涉及UI操作,需要放在Synchronize中调用以确保同步
procedure TMyThread.SetFormControlCaption;
begin
form.Label1.Caption := form.pubstr;
end;

procedure TMyThread.Execute;
begin
inherited;
FreeOnTerminate := True; {这可以让线程执行完毕后随即释放}
Synchronize(SetFormControlCaption); // 同步方式更新form1的UI(label1.caption)
end;

procedure TForm1.Button1Click(Sender: TObject);
var
myThread: TMyThread;
begin
pubstr := 'test';
myThread := TMyThread.Create(True);
myThread.form := Self;
myThread.Resume;
end;

end.


[解决办法]
线程是挂起的啊啊啊啊啊啊啊啊

读书人网 >.NET

热点推荐