TThread的中断睡眠方法(并且只有睡眠方法) [英] Interrupt Sleep method of TThread (and only Sleep method)

查看:80
本文介绍了TThread的中断睡眠方法(并且只有睡眠方法)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种能够快速中断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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆