多线程如何访问外部变量

litterant 2013-12-09 02:42:09
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
先谢谢各位!!
...全文
594 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
haitao 2013-12-11
  • 打赏
  • 举报
回复
访问是可以任意访问的 只是要注意并发写导致的异常:通过互斥加锁来保护
litterant 2013-12-11
  • 打赏
  • 举报
回复
我是业余爱好,平时不做开发,有需要时做些简单的
eclipsewangping 2013-12-10
  • 打赏
  • 举报
回复
线程是挂起的啊啊啊啊啊啊啊啊
sololie 2013-12-09
  • 打赏
  • 举报
回复
LZ这帐号不是别人给的吧,不然怎么一个02年注册的帐号还问这么基础的问题
litterant 2013-12-09
  • 打赏
  • 举报
回复
to sololie 谢谢你!
sololie 2013-12-09
  • 打赏
  • 举报
回复
另一种方式

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.
sololie 2013-12-09
  • 打赏
  • 举报
回复

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.

5,532

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧