为什么这种方式不行?procedure TMyThread.Execute;
begin
while not Terminated do
begin
if tick <= 10000 then begin
EnterCriticalSection(CriticalSection);
try
Form1.Edit1.Text :=IntToStr(tick);
Inc(tick);
finally
LeaveCriticalSection(CriticalSection);
end;
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
Mythread:TMyThread;
begin
tick:=1;
Mythread :=TMyThread.Create(False);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
InitializeCriticalSection(CriticalSection); //初始化
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
DeleteCriticalSection(CriticalSection); //删除
end;
为什么下边这种方法可以
procedure TMyThread.AddEdit;
begin
Form1.Edit1.Text :=IntToStr(tick);
Inc(tick);
end;procedure TMyThread.Execute;
begin
while not Terminated do
begin
if tick <= 10000 then begin
Synchronize(addedit);
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
Mythread:TMyThread;
begin
tick:=1;
Mythread :=TMyThread.Create(False);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
InitializeCriticalSection(CriticalSection); //初始化
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
DeleteCriticalSection(CriticalSection); //删除
end;
begin
while not Terminated do
begin
if tick <= 10000 then begin
EnterCriticalSection(CriticalSection);
try
Form1.Edit1.Text :=IntToStr(tick);
Inc(tick);
finally
LeaveCriticalSection(CriticalSection);
end;
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
Mythread:TMyThread;
begin
tick:=1;
Mythread :=TMyThread.Create(False);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
InitializeCriticalSection(CriticalSection); //初始化
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
DeleteCriticalSection(CriticalSection); //删除
end;
为什么下边这种方法可以
procedure TMyThread.AddEdit;
begin
Form1.Edit1.Text :=IntToStr(tick);
Inc(tick);
end;procedure TMyThread.Execute;
begin
while not Terminated do
begin
if tick <= 10000 then begin
Synchronize(addedit);
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
Mythread:TMyThread;
begin
tick:=1;
Mythread :=TMyThread.Create(False);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
InitializeCriticalSection(CriticalSection); //初始化
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
DeleteCriticalSection(CriticalSection); //删除
end;
Form1.Edit1.Text :=IntToStr(tick);
Inc(tick);这部分是在管道中要保护的部分,你在子线程中,实现了保护,但是,你在主线程中,没有对其进行保护,至少Form1.Edit1.Text这个没有被保护,这样,虽然你使用了临界,但是对Form1.Edit1.Text的操作依然会存在多线程(主线程和子线程)同时访问的情况。
而Synchronize却可以保证这种同步,也就是被Synchronize所指定的那个过程,会在主线程中被调用。
下面的代码是我依据楼主第一段代码复原的。在TMyThread.Execute方法中有我的注释,证明了某些人的理论是伪理论!
TEdit控件封装自Windows系统控件Edit,它依靠复杂的消息传递来操作。而消息传递只在主线程进行,但是子线程TMyThread不管,它以最快的速度给TEdit赋值,在主线程的消息来不及处理的情况下冲突报错。用Sleep(1)可以给一些消息处理的时间,可能就避免了报错。同理,并不是所有的控件都会报错,有些控件的消息处理较简单,可能还能跟得上子线程TMyThread。比如给Form1.Caption赋值。可能我说的也不完全对,请各位指正。
最后我想请各位以严谨的心态回帖,不要只是想多得些分。unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TMyThread = class(TThread)
protected
procedure Execute; override;
end; TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
CriticalSection: TRTLCriticalSection;
tick: Integer;implementation{$R *.dfm}{ TMyThread }procedure TMyThread.Execute;
begin
while not Terminated do
begin
if tick <= 1000 then begin
EnterCriticalSection(CriticalSection);
try
Sleep(1); {加上此行就不会报错了}
//Form1.Caption :=IntToStr(tick); {或者把下一行替换为此行也不会报错}
Form1.Edit1.Text :=IntToStr(tick);
Inc(tick);
finally
LeaveCriticalSection(CriticalSection);
end;
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
Mythread:TMyThread;
begin
tick:=1;
Mythread :=TMyThread.Create(False);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
InitializeCriticalSection(CriticalSection); //初始化
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
DeleteCriticalSection(CriticalSection); //删除
end;end.