TThread的中断睡眠方法(并且只有睡眠方法) [英] Interrupt Sleep method of TThread (and only Sleep method)
问题描述
我正在寻找一种能够快速中断TThread
的功能.
I am looking for an ability to interrupt TThread
quickly.
有人建议用TerminateThread
打断它,但我不希望这种暴力行为.
Some suggest to interrupt it with TerminateThread
, but I do not want this violence.
我在Execute
方法中实现了退出检查,但是我不能影响一件事:正在进行的Sleep
.当Sleep
中有线程时,剩下的唯一事情就是等到Sleep
完成.
I implemented an exit check in Execute
method, but there is one thing I cannot influence: an ongoing Sleep
. When a thread is in Sleep
the only thing left to me is to wait until Sleep
finishes.
我做了以下解决方法:
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
而不是线程?
Is there an ability to interrupt Sleep
, but not the thread?
推荐答案
使用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()
),正在进行的任何睡眠都将停止.立即.
This way, while the thread is running normally, _smartSleep()
will sleep more efficiently, and as soon as you Terminate()
the thread (as Terminate()
calls TerminatedSet()
), any sleep that is in progress will stop immediately.
* 如果在XE2之前使用的是Delphi版本,则必须实现自己的方法以在需要时发信号通知TEvent
.例如,向线程类添加一个公共Stop()
方法,并使其调用Terminate()
和FTermEvent.SetEvent()
,然后调用该方法,而不是直接调用Terminate()
.
* If you are using a Delphi version prior to XE2, you will have to implement your own method to signal the TEvent
when needed. For example, adding a public Stop()
method to the thread class and have it call Terminate()
and FTermEvent.SetEvent()
, then call that method instead of calling Terminate()
directly.
这篇关于TThread的中断睡眠方法(并且只有睡眠方法)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!