读书人

为什么这个线程停不下来?该如何解决

发布时间: 2012-03-17 19:06:28 作者: rapoo

为什么这个线程停不下来???
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; 

读书人网 >.NET

热点推荐