按照一般的delphi书上的介绍:多线程是不能访问主线程的vcl控件的。如果一定要访问,则必须使用synchronize函数。
于是我写了一个测试程序,很短,功能:用一个线程在主程序界面上的edit1.text里面显示1-1000000的数字。分别用了synchronize函数和没用用。 问题:为什么没有用synchronize函数程序运行正常,用了synchronize函数反而出现问题???////////////////////////// 程序1//////////////////////////////
没有使用synchronize函数,但测试结果,程序运行正常。
/////////////////////////////////////////////////////////////
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;type
tmythread = class(Tthread)
private
protected
procedure execute; override ;
procedure giveanswer;
end;var
Form1: TForm1;
var
exc:boolean;
i:integer;implementation{$R *.dfm}procedure tmythread.execute;
begin
freeonterminate:=true;
for i:=1 to 10000000 do
begin
if exc=false then break;
form1.Edit1.Text :=inttostr(i);
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
exc:=true;
tmythread.Create(false);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
exc:=false;
end;end.
////////////////////////// 程序2//////////////////////////////
使用synchronize函数。测试结果,可以正常运行,但如果在运行过程中
移动了程序的窗体,或者改变窗体的大小,程序会无响应。
/////////////////////////////////////////////////////////////
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;type
tmythread = class(Tthread)
private
protected
procedure execute; override ;
procedure giveanswer;
end;var
Form1: TForm1;
var
exc:boolean;
i:integer;implementation{$R *.dfm}procedure Tmythread.giveanswer ;
begin
form1.Edit1.Text :=inttostr(i);
end;
procedure tmythread.execute;
begin
freeonterminate:=true; for i:=1 to 10000000 do
begin
if exc=false then break;
synchronize(giveanswer);
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
exc:=true;
tmythread.Create(false);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
exc:=false;
end;end.
于是我写了一个测试程序,很短,功能:用一个线程在主程序界面上的edit1.text里面显示1-1000000的数字。分别用了synchronize函数和没用用。 问题:为什么没有用synchronize函数程序运行正常,用了synchronize函数反而出现问题???////////////////////////// 程序1//////////////////////////////
没有使用synchronize函数,但测试结果,程序运行正常。
/////////////////////////////////////////////////////////////
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;type
tmythread = class(Tthread)
private
protected
procedure execute; override ;
procedure giveanswer;
end;var
Form1: TForm1;
var
exc:boolean;
i:integer;implementation{$R *.dfm}procedure tmythread.execute;
begin
freeonterminate:=true;
for i:=1 to 10000000 do
begin
if exc=false then break;
form1.Edit1.Text :=inttostr(i);
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
exc:=true;
tmythread.Create(false);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
exc:=false;
end;end.
////////////////////////// 程序2//////////////////////////////
使用synchronize函数。测试结果,可以正常运行,但如果在运行过程中
移动了程序的窗体,或者改变窗体的大小,程序会无响应。
/////////////////////////////////////////////////////////////
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;type
tmythread = class(Tthread)
private
protected
procedure execute; override ;
procedure giveanswer;
end;var
Form1: TForm1;
var
exc:boolean;
i:integer;implementation{$R *.dfm}procedure Tmythread.giveanswer ;
begin
form1.Edit1.Text :=inttostr(i);
end;
procedure tmythread.execute;
begin
freeonterminate:=true; for i:=1 to 10000000 do
begin
if exc=false then break;
synchronize(giveanswer);
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
exc:=true;
tmythread.Create(false);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
exc:=false;
end;end.
begin
if exc=false then break;
synchronize(giveanswer);
sleep(10); //正常要加這句
end; IFindit(寻找其中的乐趣) ( ) 信誉:100
基本表達了正确的意思了
可以访问,但VCL不是线程安全的,即如果你在线程中操作VCL。
同时你在主线程中也要操作该VCL,那些就会出现危险了。是这个意思
http://dev.csdn.net/develop/article/22/22467.shtm
http://dev.csdn.net/develop/article/22/22468.shtm
http://dev.csdn.net/develop/article/22/22469.shtm
http://dev.csdn.net/develop/article/22/22470.shtm