TThread的中断睡眠方法(仅睡眠方法)

Pau*_*aul 0 delphi multithreading

我正在寻找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;
Run Code Online (Sandbox Code Playgroud)

但看起来不太好.

是否有能力中断Sleep,但不是线程?

Rem*_*eau 8

使用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;
Run Code Online (Sandbox Code Playgroud)

这样,当线程正常运行时,_smartSleep()将更有效地睡眠,并且一旦Terminate()线程(作为Terminate()调用TerminatedSet()),任何正在进行的睡眠将立即停止.

*如果您在XE2之前使用Delphi版本,则必须实现自己的方法以TEvent在需要时发出信号.例如,添加一个公共Stop()方法的线程类,并让它调用Terminate()FTermEvent.SetEvent(),然后调用该方法,而不是调用的Terminate()直接.

  • TThread析构函数恢复挂起的线程并等待其终止。但是由于`FTermEvent`在调用基本析构函数之前已被释放,因此在恢复线程时会发生不好的事情。永远不要试图破坏从未开始运行或正在运行的线程。在销毁线程之前,请始终明确恢复并终止线程。 (2认同)