为什么这个线程停不下来???
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后线程还是在运行,根本没挂起???请指教,谢谢
[解决办法]
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;
在你线程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的方法。
[解决办法]
procedure TMyThread.Execute;
begin
FreeOnTerminate := True;
Synchronize(SetValue);
end;
Synchronize 这么写是不行的,等于把操作放到主线程去执行了,你自己线程控制不了
[解决办法]
你把操作全放到主线程了,跟没用线程一样。
应该像我这样用线程。
- Delphi(Pascal) code
procedure TMyThread.Execute;begin FreeOnTerminate := True;for i := 0 to 100000 do Synchronize(SetValue);end;
[解决办法]
我给你讲讲吧
- Delphi(Pascal) code
Synchronize 是VCL中所谓线程同步方法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;