我正在寻找快速中断TThread
的能力。
有人建议用TerminateThread
打断它,但我不想要这种暴力行为。
我在Execute
方法中实施了退出检查,但有一件事我无法影响:正在进行Sleep
。当一个帖子在Sleep
时,我唯一要做的就是等到Sleep
完成。
我做了以下解决方法:
procedure TMyThreadTimer._smartSleep(Timeout: Integer);
var
repeats: Integer;
begin
repeats := (Timeout div 50) + 1;
while (not Terminated) and (repeats > 0) do begin
Sleep(50);
Dec(repeats);
end;
end;
但看起来不太好。
是否有能力中断Sleep
,但不能中断线程?
答案 0 :(得分:7)
使用TEvent
对象代替Sleep()
,例如:
type
TMyThreadTimer = class(TThread)
private
FTermEvent: TEvent;
procedure _smartSleep(Timeout: Integer);
protected
procedure Execute; override;
procedure TerminatedSet; override; // XE2+ only *
public
constructor Create(ACreateSuspended: Boolean); override;
destructor Destroy; override;
end;
constructor TMyThreadTimer.Create(ACreateSuspended: Boolean);
begin
inherited Create(ACreateSuspended);
FTermEvent := TEvent.Create(nil, True, False, '');
end;
destructor TMyThreadTimer.Destroy;
begin
//inherited calls TerminatedSet where FTermEvent should not be freed yet
inherited;
FTermEvent.Free;
end;
procedure TMyThreadTimer.Execute;
begin
...
end;
procedure TMyThreadTimer.TerminatedSet;
begin
FTermEvent.SetEvent;
end;
procedure TMyThreadTimer._smartSleep(Timeout: Integer);
begin
FTermEvent.WaitFor(Timeout);
end;
这样,当线程正常运行时,_smartSleep()
将更有效地睡眠,并且只要您Terminate()
线程(Terminate()
调用TerminatedSet()
),任何正在进行的睡眠都会立即停止。
* 如果您使用的是XE2之前的Delphi版本,则必须实施自己的方法,以便在需要时发出TEvent
信号。例如,向线程类添加公共Stop()
方法并让其调用Terminate()
和FTermEvent.SetEvent()
,然后调用该方法,而不是直接调用Terminate()
。