DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: wanggui999
今日帖子: 30
在线用户: 11
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 10:38:13
标题:
请教大家一个关于定时线程的内容 浏览:875
加入我的收藏
楼主: 从陈达宽的delphi深度理想这本书中看到了这么个例子。但是有个问题,就是开启线程的时候,我可以用TimerThread.Create来运行,那我如果要停止呢。用了TimerThread.Terminate好像并不行啊
此帖子包含附件:
PNG 图像
大小:135.8K
----------------------------------------------
-
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 10:38:48
1楼: 图二
此帖子包含附件:
PNG 图像
大小:191.7K
----------------------------------------------
-
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 10:53:14
2楼: 就是说我想停止她运行,有什么更加好用的办法
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2022/5/21 10:59:44
2楼: 在thread中使用Timer就是脱裤子放屁,调用线程的Terminate方法,需要线程的Execute去检测Terminated来终止执行,他这个代码就是个垃圾,完全就是误导人,线程不是这样用的。楼主你可以百度一下TTimerThread,有那种用WaitForSingleObject和CreateEvent来实现的例子。
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 11:04:25
3楼: ExitThread(Timerthread,0),貌似也不行
----------------------------------------------
-
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 11:06:05
4楼: iamdream实现定时运行也可以码?
----------------------------------------------
-
作者:
男 dmzn (dmzn) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 11:35:14
5楼: 因为线程已经结束了,只留了一个线程对象.你能做的只剩TimerThread.Free
触发OnTimer的也不是线程,而是系统WM_Timer消息.
----------------------------------------------
生活愉快.
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2022/5/21 11:39:10
5楼: 参考以下例子,把你要执行的代码放到OnTimer里就可以了。注意:这个实现是通过Enabled来设置运行或暂停的,不要用Terminate,并且Enabled只应在主线程中改变,不要在线程里设置这个属性。
http://t.zoukankan.com/findumars-p-5510782.html
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 jackalan (nVicen) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 11:56:44
6楼: 这个例子真是看不懂,写这本书的实在是高人。
----------------------------------------------
简单做人,认真做事。
作者:
男 tuesdays (Tuesday) ▲▲▲△△ -
注册会员
2022/5/21 12:31:12
7楼: 要发信号进去,  线程里面的循环体中, 要随时判断信号是否变化. 

100%的线程都是进入循环(不循环的线程, 搞不懂你在做什么. )
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 13:00:43
8楼: 谢谢我是梦,我装一个试试看。@dmzn,那就是说没有办法来改变对吧
----------------------------------------------
-
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 13:03:02
9楼: 另外后来我又翻看了后面几页,她给出了方案,但是好像也还是关闭不了执行的线程
此帖子包含附件:
PNG 图像
大小:151.5K
----------------------------------------------
-
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 13:03:31
10楼: 续页
此帖子包含附件:
PNG 图像
大小:311.8K
----------------------------------------------
-
作者:
男 luckyso999 (luckyso) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 13:48:13
6楼:   TThread.CreateAnonymousThread(
    procedure
     begin
       sleep(10000);
      
      //做些事

     end).Start;

  这样不就行了
----------------------------------------------
-
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 14:01:12
11楼: @luckyso999,关键如果我想要停止这个线程呢
----------------------------------------------
-
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 14:47:08
12楼: 或者我在搞个简单点的例子。比如说我建了一个线程unit3,用途是一旦系统时间和Datatimepick设置的时间一样,她就执行XXX

现在回到主Form,有2个button
1.button-->timep.create //正常执行
2.button-->我怎么样才可以停止线程执行
此帖子包含附件:
PNG 图像
大小:40.3K
----------------------------------------------
-
作者:
男 keymark (嬲) ▲▲△△△ -
注册会员
2022/5/21 15:35:05
14楼: 发消息给线程 
线程处理消息
消息可以是   停工

https://github.com/jmfjorge/DelphiThreadedtimer/blob/master/YMThreadTimer.pas
https://codereview.stackexchange.com/questions/153819/ttimerthread-threaded-timer-class
https://stackoverflow.com/questions/12026951/using-vcl-ttimer-in-delphi-console-application
https://en.delphipraxis.net/topic/6621-tthreadedtimer/?tab=comments#comment-57420
https://delphi.cjcsoft.net/viewthread.php?tid=47384
http://mahasi.egloos.com/2135637
https://torry.net/quicksearchd.php?String=Timer&Title=Yes
https://www.cnblogs.com/findumars/p/5648525.html
随便搜搜一大把。
以前的书可能还没现在搜的代码看得明白 关键词搜索下就行了。(技术累积)
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 15:46:50
15楼: 谢谢楼上的兄弟,我研究研究
----------------------------------------------
-
作者:
男 supermay (supermay) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 16:51:15
16楼: unit UTAbstractTimerThread;

interface

uses
  Classes, Windows;

type
  TAbstractTimerThread = class(TThread)
  private
    FCheckDelta: Cardinal;
    FCheckEvent: THandle;
    FEnabled: Boolean;
    FActiveHandle: THandle;
    FOnThreadTimer: TNotifyEvent;
    procedure SetEnabled(const Value: Boolean);
  protected
    {----------
      过程名:    Execute
      过程作用:  线程类的执行体
      作者:      Freeman
      日期:      2010.01.15
      参数:      无
      返回值:    无
    ----------}
    procedure Execute; override;
    {----------
      过程名:    initialize
      过程作用:  线程的初始化过程,用作内部变量等的初始化工作
      作者:      Freeman
      日期:      2010.01.15
      参数:
      返回值:    无
    ----------}
    procedure initialize(); virtual;
    {----------
      过程名:    finalize
      过程作用:  线程的释放过程,用作内部变量等的释放工作
      作者:      Freeman
      日期:      2010.01.15
      参数:
      返回值:    无
    ----------}
    procedure finalize(); virtual; abstract;
    {----------
      过程名:    working
      过程作用:  线程的工作函数
      作者:      Freeman
      日期:      2010.01.15
      参数:
      返回值:    无
    ----------}
    procedure working();
    {----------
      过程名:    workFinished
      过程作用:  用作线程工作完成的标志重置
      作者:      Freeman
      日期:      2010.01.15
      参数:
      返回值:    无
    ----------}
    procedure workFinished(); virtual;
    {----------
      过程名:    doWork
      过程作用:  线程的真正工作函数
      作者:      Freeman
      日期:      2010.02.25
      参数:
      返回值:    无
    ----------}
    procedure doWork(); virtual; abstract;
  public
    {----------
        过程名:    Create
        过程作用:  线程的构造函数,线程创建起后自动挂起
        作者:      Freeman
        日期:      2010.01.15
        参数:
        返回值:    无
      ----------}
    constructor Create();
    {----------
      过程名:    Destroy
      过程作用:  线程的析构函数,
      作者:      Freeman
      日期:      2010.01.15
      参数:      无
      返回值:    无
    ----------}
    destructor Destroy; override;
    {----------
      过程名:    StopThread
      过程作用:  线程的中止函数
      作者:      Administrator
      日期:      2010.01.15
      参数:
      返回值:    无
    ----------}
    procedure StopThread(); virtual;

    procedure wake();
    //轮询时间间隔
    property CheckDelta: Cardinal read FCheckDelta write FCheckDelta;
    //是否起效
    property Enabled: Boolean read FEnabled write SetEnabled;
  end;

implementation

{ TAbstractTimerThread }

constructor TAbstractTimerThread.Create;
begin
  inherited Create(True);
  self.FreeOnTerminate := True;

  FCheckDelta := 1000;

  FEnabled := false;

  FActiveHandle := CreateEvent(nil, True, False, nil);

  FCheckEvent := CreateEvent(nil, False, False, nil);
  self.initialize;
end;

destructor TAbstractTimerThread.Destroy;
begin
  self.finalize;
  if FCheckEvent > 0 then
    CloseHandle(FCheckEvent);

  if FActiveHandle > 0 then
    CloseHandle(FActiveHandle);

  inherited;
end;

procedure TAbstractTimerThread.Execute;
var
  hResult: Cardinal;
begin
  while not Terminated do
  begin
    //等待开始
    WaitForSingleObject(FActiveHandle, INFINITE);

    //中止线程时结束本次循环
    if Self.Terminated then
      Break;

    //等待时钟
    //不是中止才执行工作函数
    hResult := WaitForSingleObject(FCheckEvent, FCheckDelta);
    case hResult of
      WAIT_OBJECT_0:
        begin
          //空
        end;
      WAIT_TIMEOUT:
        begin
          self.working;
        end;
    end;

  end;
end;

procedure TAbstractTimerThread.initialize;
begin
  self.wake;
end;

procedure TAbstractTimerThread.SetEnabled(const Value: Boolean);
begin
  FEnabled := Value;
  if FEnabled then
  begin
    SetEvent(FActiveHandle);
  end
  else
  begin
    ResetEvent(FActiveHandle);
  end;
end;

procedure TAbstractTimerThread.StopThread;
begin
  self.Terminate;
  if not FEnabled then
    Self.Enabled := True;

  workFinished;
end;

procedure TAbstractTimerThread.wake;
begin
  if self.Suspended then
    self.Resume;

  if FEnabled then
  begin
    SetEvent(FActiveHandle);
  end
  else
  begin
    ResetEvent(FActiveHandle);
  end;
end;

procedure TAbstractTimerThread.workFinished;
begin
  SetEvent(FCheckEvent);
end;

procedure TAbstractTimerThread.working;
begin
  self.doWork;
end;

end.
----------------------------------------------
https://shop66090024.taobao.com/?spm=a313o.7775905.1998679131.d0011.6f6f2796Z7e3JX
作者:
男 supermay (supermay) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 16:52:04
17楼: unit UTThreadTimer;

interface

uses
  Classes, UTAbstractTimerThread;

type
  TThreadTimer = class(TAbstractTimerThread)
  private
    FOnThreadTimer: TNotifyEvent;
    procedure doThreadTimerEvent();
  protected
    {----------
       过程名:    doWork
       过程作用:  线程的真正工作函数
       作者:      Freeman
       日期:      2010.02.25
       参数:
       返回值:    无
     ----------}
    procedure doWork(); override;
    procedure initialize(); override;
    procedure finalize(); override;
  published

  public
    //线程时钟事件
    property OnThreadTimer: TNotifyEvent read FOnThreadTimer write FOnThreadTimer;
  end;
implementation

{ TThreadTimer }

procedure TThreadTimer.doThreadTimerEvent;
begin
  if Assigned(FOnThreadTimer) then
    FOnThreadTimer(Self);
end;

procedure TThreadTimer.doWork;
begin
  inherited;
  if Assigned(Self) then
    self.Synchronize(doThreadTimerEvent);
end;

procedure TThreadTimer.finalize;
begin
  inherited;

end;

procedure TThreadTimer.initialize;
begin
  inherited;

end;

end.
----------------------------------------------
https://shop66090024.taobao.com/?spm=a313o.7775905.1998679131.d0011.6f6f2796Z7e3JX
作者:
男 supermay (supermay) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 16:52:59
18楼: unit UTimerEx;

interface

uses
  SysUtils, Classes, UTThreadTimer;

type
  TimerEx = class(TComponent)
  private
    FThreadTimer: TThreadTimer;
    FOnTimer: TNotifyEvent;
    procedure SetEnabled(value: Boolean);
    procedure SetInterval(value: Cardinal);
    procedure ThreadTimerEvent(Sender: TObject);
    function GetPriority: TThreadPriority;
    procedure SetPriority(const Value: TThreadPriority);
    function GetEnabled: Boolean;
    function GetInterval: Cardinal;
  protected
    { Protected declarations }
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Enabled: Boolean read GetEnabled write SetEnabled default False;
    property Interval: Cardinal read GetInterval write SetInterval default 1000;
    property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
    property Priority: TThreadPriority read GetPriority write SetPriority default tpNormal;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('timers', [TimerEx]);
end;

{ TTimer }

constructor TimerEx.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FThreadTimer := TThreadTimer.Create;
  FThreadTimer.OnThreadTimer := ThreadTimerEvent;
end;

destructor TimerEx.Destroy;
begin
  if Assigned(FThreadTimer) then
  begin
    FThreadTimer.StopThread;
    FThreadTimer := nil;
  end;
  inherited;
end;

function TimerEx.GetEnabled: Boolean;
begin
  Result := False;
  if Assigned(FThreadTimer) then
  begin
    Result := FThreadTimer.Enabled;

  end;
end;

function TimerEx.GetInterval: Cardinal;
begin
  Result := 1000;
  if Assigned(FThreadTimer) then
  begin
    Result := FThreadTimer.CheckDelta;
  end;
end;

function TimerEx.GetPriority: TThreadPriority;
begin
  Result := tpIdle;
  if Assigned(FThreadTimer) then
    Result := FThreadTimer.Priority;
end;

procedure TimerEx.SetEnabled(value: Boolean);
begin
  if Assigned(FThreadTimer) then
    FThreadTimer.Enabled := value;
end;

procedure TimerEx.SetInterval(value: Cardinal);
begin
  if Assigned(FThreadTimer) then
    FThreadTimer.CheckDelta := value;
end;

procedure TimerEx.SetPriority(const Value: TThreadPriority);
begin
  if Assigned(FThreadTimer) then
    FThreadTimer.Priority := value;
end;

procedure TimerEx.ThreadTimerEvent(Sender: TObject);
begin
  if self.ComponentState <> [csDesigning] then
  begin
    if Assigned(FOnTimer) then
      FOnTimer(self);
  end;

end;

end.
----------------------------------------------
https://shop66090024.taobao.com/?spm=a313o.7775905.1998679131.d0011.6f6f2796Z7e3JX
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 17:41:49
19楼: 感谢大侠
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/5/21 18:27:54
20楼: 2 楼说得对。

楼主,你不用看他这个如何释放了,没有意义。

楼主,你要的是:究竟搞一个定时的线程来做什么。

假设你就需要一段代码干活,但是呢,你需要这段代码,定时干活。比如,20秒干一次活,那么,你就可以搞一个线程,在线程里面搞一个死循环:

procedrure TMyThread.Execute;
begin
  //假设这里有一些线程开始时的初始化代码,比如创建一些这个线程执行需要的对象的实例。
while True do
begin
  if Self.Terminated then Break; //如果外面调用了线程的 Terminate 方法,实际上这个方法就是设置了线程的 Terminated 属性。而线程的结束,就是线程的死循环跳出来,线程执行到结尾,自然就结束。

  DoMyJob();

  TEvent.Wait(10秒); //实际上这里的单位是毫秒,自己换算10秒是多少。
end;

  //假设这里还有一些线程结束时需要执行的代码,执行到这里,线程自己就结束了;
end; 


线程的代码,就是如此简单。那个 DoMyJob 函数或者方法,你随便写在哪里。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/5/21 18:32:19
21楼: 另外,我看见上面有代码,是用的 Sleep(10秒)这样的。这里最好用 TEvent 来阻塞线程,而不是用 Sleep,因为,假设你现在需要结束线程,你执行了 MyThread.Terminate;那么,线程刚好在 Sleep,那你就要等10秒后,线程才能结束。

解决这个问题有2个方法:
1. Sleep(10秒) 拆成一个循环
for i := 0 to 9 do
begin
  Sleep(1秒);
  if Self.Terminated then Break;
end;

这样,你睡一秒就检查一次,那么,最多1秒,你的线程可以结束。

但是,如果你用 TEvent 来阻塞,当你要线程结束,就可以这样写:

MyThread.Terminate;
TEvent.SetEvent;

这个 SetEvent 就是让那个 TEvent.Wait 被唤醒,解除阻塞,它就不等 10 秒了,而是立即执行下一句,于是它马上就退出了。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/5/21 18:33:12
22楼: Delphi 的资料比较少,很少那种【最佳实践】的教程。我这些经验是我自己写了很多代码以后总结的。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/5/21 18:35:49
23楼: 还有,线程循环中,一定要加 Sleep 或者 TEvent.wait;总之要阻塞它。

while True do
begin
  Sleep(10);
end;

上述代码,别看线程10毫秒就唤醒一次跑一个循环,但并不占 CPU;

while True do
begin
  X := X + Y;
end;

上述循环,会把 CPU 给你跑满 100%;所以,应该改成:

while true do
begin
  X := X + Y;
  Sleep(10);
end;
----------------------------------------------
-
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 18:48:33
24楼: 多年前,网上有2个线程流行的(大概d5就有了吧)
THardWorkThread 和 TLongTimeWaitThread
我自己也修改了下,适合我用的(当年是用于工控数据采集)

请参考: https://blog.csdn.net/jankercsdn/article/details/51323690
----------------------------------------------
-
作者:
男 tuesdays (Tuesday) ▲▲▲△△ -
注册会员
2022/5/21 18:59:27
25楼: 线程常识:
  必须有循环才叫线程.
  凡是遇到任何错误异常, 请直接用exit.

掌握了就简单.
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 19:00:28
25楼: 不管如何让线程停止,循环工作的线程都不会马上停止的,即使是Terminate命令。
线程变量释放前,一般要做WaitFor()判断,要求严格的要做一个循环判断,直到真正结束。
还有,D7以后(大概是吧),线程的Suspend()和Resume()已经标记deprecated,相关功能最好自己实现。
----------------------------------------------
-
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/21 20:09:18
26楼: 谢谢以上各位兄弟的帮助
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/5/21 22:19:18
27楼: 25 楼,线程遇到异常,不需要退出。做好异常处理就行了。

当然,必须捕获异常,否则这个线程就完全跑飞失控了。

也就是说,必须这样写:

while True do
begin
  try
    do your business;
  except
    //在这里把异常处理好,你的线程循环可以继续..........
  end;
end;
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
注册会员
2022/5/22 0:01:15
28楼: the Thread basically should have a "point to controls" when STOP or not!

NOTE IMPORTANT:

NEVER RAISE AN EXCEPTION INTO THREADS!!!
ELSE, YOUR APP WILL CRASH FOR SURE!




Using "TThread" class as base:

1) inherit from this class by default
2) override the "Execute" procedure ( at least)
3) put a "point of control" in each "part" sensible to stop it.
4) tests, tests, tests ....


ex.: NOTE: I use TEvent to controls too! but this code is enought for works!

in FormMain im just a variable or similar to say: STOP PLEASE!
...
implementation

var
  MyThreadsWithEvent  : TArray<TMyThreadWithEvent>;
  //
  MyThreadsStopAll :boolean = false;

...

procedure TViewFormMain.Btn_Thread_StopClick(Sender: TObject);
begin
  MyThreadsStopAll := true;
end;

procedure TViewFormMain.Btn_Create_EventsClick(Sender: TObject);
begin
...
  MyThreadsWithEvent := MyThreadsWithEvent + [TMyThreadWithEvent.Create(1)];
  MyThreadsWithEvent := MyThreadsWithEvent + [TMyThreadWithEvent.Create(2)];

  for var MyItem in MyThreadsWithEvent do
    MyItem.Start;
...
end;
----------

in my Thread class I have:

unit uProcessEvent;

interface

uses
  System.Classes,
  System.SyncObjs;

type
  TMyThreadWithEvent = class(TThread)
  private
    FIndex: integer;
  protected
    procedure Execute; override;
  public
    constructor Create(AValue: integer; ASuspended: boolean = true);
    // procedure MyOnTerminate(Sender: TObject);
  end;

implementation

...

constructor TMyThreadWithEvent.Create(AValue: integer; ASuspended: boolean = true); // <---
begin
  inherited Create(ASuspended); // YEAH, start suspended! ... wait my command!!!
  //
  FIndex          := AValue;
  // OnTerminate     := MyOnTerminate;
  FreeOnTerminate := false; // important in some situations!!!
end;

procedure TMyThreadWithEvent.Execute;
var
  FStatus: TWaitResult;
begin
  //
  // ALWAYS TEST YOUR "POINT OF CONTROL" -> in my case, Im testing just here
  //
  while not(MyThreadsStopAll) do // <--- the magic is always observe it in "each" sensible task!!!
  begin
    if MyThreadsStopAll then
      break;
    //
    // FStatus := MyEventSharedWithAllThreads.WaitFor(MyEventTimeOutValue); // for my TEvent use
    //
    if MyThreadsStopAll then  // <---- the magic!!!
      break;
    //
(*  my tests...
    TThread.Synchronize(nil,
      procedure
      begin
        if (Self.FIndex = 1) then
          ViewFormMain.LstBxThreadA.Items.Add(Self.ThreadID.MyText + ' -> ' + FStatus.MyText + ' ' + TimeToStr(now, MyFS))
        else
          ViewFormMain.LstBxThreadB.Items.Add(Self.ThreadID.MyText + ' -> ' + FStatus.MyText + ' ' + TimeToStr(now, MyFS));
      end);
*)
    //
    sleep(1); // just for "provocate" a time on cpu...
  end;
end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!
作者:
男 zhouying (zy) ★☆☆☆☆ -
盒子活跃会员
2022/5/22 10:12:33
29楼: 说到这里,索性还有个问题一并提问了。因为我这个定时的功能开启后,还设置了自动关闭时间,所以最初的设计是在线程中开启后,自动在开启一个timer进行倒计时。是不是在线程里面加timer这种设计不太好?
----------------------------------------------
-
作者:
男 sail2000 (小帆工作室) ★☆☆☆☆ -
盒子活跃会员
2022/5/22 11:06:01
30楼: 1,设计线程时要给标识,当while遇上这标识就应该退出while
2,要退出线程首先 Terminate,再 Waitfor 最后 Free


具体像这样:
AThread.StopRun := True;//标识
AThread.Terminate;通知线程结束
AThread.WaitFor;//等待结束
AThread.Free;//释放
----------------------------------------------
delphi 是兴趣,和工作无关,即使它倒闭。
又不靠它 delphi 吃饭,怕甚?
作者:
男 wiseinfo (wisienfo) ★☆☆☆☆ -
普通会员
2022/5/22 13:01:46
31楼: 多线程不过关, 用QDAC的QWorkers
----------------------------------------------
-
作者:
男 jackalan (nVicen) ★☆☆☆☆ -
盒子活跃会员
2022/5/22 16:24:58
32楼: 搞这么复杂,累死了。

unit Unit3;

interface

uses System.Classes, Vcl.Comctrls, SysUtils;

type
  TimeP = class(TThread)
  private
    //
  protected
    procedure Execute; override;
  end;

var
  myTimeThread : TimeP;

implementation
uses unit1;

procedure TimeP.Execute;
begin
  while not Terminated do
  begin
    Sleep(1000);
    if formatdatetime('hh:mm:ss', now) = formatdatetime('hh:mm:ss', form1.DateTimePicker1.Time) then
      form1.Caption := TimetoStr(form1.DateTimePicker1.Time); 
  end;
end;

使用 : 
var myTimeThread : TimeP;
//创建线程
myTimeThread := TimeP.Create;
//终止线程
myTimeThread.Terminate;
----------------------------------------------
简单做人,认真做事。
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/5/23 11:51:22
33楼: 29 楼,既然用线程了,就不应该用 Timer。
----------------------------------------------
-
作者:
男 roadrunner (roadrunner) ★☆☆☆☆ -
盒子活跃会员
2022/5/23 12:18:21
34楼: 为什么老有人研究用线程实现定时器这么奇葩的想法

定时器这么一个破事,想想都会觉得用线程来做极端的不合理呀,这就是典型的找抽型代码。

老实交给操作系统不好吗
----------------------------------------------
-
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2022/5/23 15:08:21
35楼: 线程的友好终止就是线程的函数执行完毕。
很多线程都有一个while循环,判断线程的terminiated标识,要是true就中断循环,结束函数。TimerThread.Terminate不过就是设置了这个标识而已。
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
男 supermay (supermay) ★☆☆☆☆ -
盒子活跃会员
2022/5/25 15:24:44
37楼: 34楼
timer的优先级很低的,会被其他线程阻塞的,在堆积一堆的timer事件在比较空闲时调用的。
----------------------------------------------
https://shop66090024.taobao.com/?spm=a313o.7775905.1998679131.d0011.6f6f2796Z7e3JX
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行140.625毫秒 RSS