type
TMyThread = class(TThread)
protected
procedure Execute; override;
procedure SetValue;
public
end;procedure TMyThread.Execute;
begin
FreeOnTerminate := True;
Synchronize(SetValue);
end;procedure TMyThread.SetValue;
var
i: Integer;
begin
for i := 0 to 100000 do
begin
Application.ProcessMessages;
if self.Terminated then Break;
form1.Edit1.Text := IntToStr(i);
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
MyThread := TMyThread.Create(false);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
MyThread.Suspend;//???怎么停不下来
end;为什么执行MyThread.Suspend后线程还是在运行,根本没挂起???请指教,谢谢
TMyThread = class(TThread)
protected
procedure Execute; override;
procedure SetValue;
public
end;procedure TMyThread.Execute;
begin
FreeOnTerminate := True;
Synchronize(SetValue);
end;procedure TMyThread.SetValue;
var
i: Integer;
begin
for i := 0 to 100000 do
begin
Application.ProcessMessages;
if self.Terminated then Break;
form1.Edit1.Text := IntToStr(i);
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
MyThread := TMyThread.Create(false);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
MyThread.Suspend;//???怎么停不下来
end;为什么执行MyThread.Suspend后线程还是在运行,根本没挂起???请指教,谢谢
解决方案 »
- TCP丢包和异常断开。
- 乱码问题:一文本文件,用写字板打开中文显示为乱码,用记事本打开中文显示正常,所以估记该文件编码为utf8类型,那么如何用stringlist加载该文本文件后,读出正确的内容并修改后再用savetofile保存呢?
- 菜鸟提问:如何减小编译后文件大小
- 求DELPHI用ADO连接MYSQL的 连接字符串!!!!!!!!!!!!!
- stringgrid 中数据显示!!!
- 如何调用动态库中的函数?(进者有分)
- 防止form被强制关闭
- 关于程序发布的小问题,请来帮小弟一把吧!
- 动态创建DBchart的问题
- 如何使一个窗体不随意退出,简单的问题
- 函数嵌套变量传值问题
- 求指导!!!如何判断一段字符为链接
var
i: Integer;
begin
for i := 0 to 100000 do
begin
Application.ProcessMessages;
if self.Terminated then Break;
form1.Edit1.Text := IntToStr(i);
end;
end;在你线程Suspend的时候,这里是不受影响的,它还是会继续执行procedure TMyThread.Execute;
var
i :Integer;
begin
FreeOnTerminate := True;
for i := 0 to 100000 do
begin
Application.ProcessMessages;
if self.Terminated then Break;
form1.Edit1.Text := IntToStr(i);
end;
end;这样就能看到效果,但是线程中不推荐操作VCL,另外 Synchronize方法一般是受信主线程中操作VCL的方法。
begin
FreeOnTerminate := True;
Synchronize(SetValue);
end;Synchronize 这么写是不行的,等于把操作放到主线程去执行了,你自己线程控制不了
应该像我这样用线程。procedure TMyThread.Execute;
begin
FreeOnTerminate := True;
for i := 0 to 100000 do
Synchronize(SetValue);
end;
procedure TMyThread.SetValue;
var
i: Integer;
begin
if self.Terminated then Break;
form1.Edit1.Text := IntToStr(i);
end;
为什么同样是操作form1.Edit1,Synchronize(SetValue)是放到主线程中,而第二种不是了???
procedure TThread.Synchronize(Method: TThreadMethod);
begin
// FSynchronize是一个结构体, 里边保存线程对象和要执行的函数
FSynchronize.FThread := Self;
FSynchronize.FSynchronizeException := nil;
FSynchronize.FMethod := Method;
Synchronize(@FSynchronize); // 这里才是最主要的
end;
// 我把Linux下的代码删了
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord);
var
SyncProc: TSyncProc;
begin
if GetCurrentThreadID = MainThreadID then
ASyncRec.FMethod // 如果当前是主线程,执行你要执行的同步函数
else
begin
{$IFDEF MSWINDOWS} // 当前线程不是主线程,则执行下边的
SyncProc.Signal := CreateEvent(nil, True, False, nil); // 创建一个事件, 无信号状态。
try
{$ENDIF}
// 进入临界区
EnterCriticalSection(ThreadLock);
try
if SyncList = nil then
SyncList := TList.Create;
SyncProc.SyncRec := ASyncRec;
SyncList.Add(@SyncProc); // 这段主要是用一个列表保存要同步的函数,用临界区保护起来
SignalSyncEvent; // 将事件设为有信号
// WakeMainThread 是个全局变量 , 在FORM单元里赋值,里边过程有点小复杂,
if Assigned(WakeMainThread) then
WakeMainThread(SyncProc.SyncRec.FThread); // 在这里边执行同步函数
{$IFDEF MSWINDOWS}
LeaveCriticalSection(ThreadLock); // 离开临界区
try
WaitForSingleObject(SyncProc.Signal, INFINITE); // 等待结束
finally
EnterCriticalSection(ThreadLock);
end;
{$ENDIF}
finally
LeaveCriticalSection(ThreadLock);
end;
{$IFDEF MSWINDOWS}
finally
CloseHandle(SyncProc.Signal);
end;
{$ENDIF}
if Assigned(ASyncRec.FSynchronizeException) then raise ASyncRec.FSynchronizeException;
end;
end;
你暂停不了是因为要同步的函数已经被赋给全局变量了,你暂停只是暂停了你的线程