上篇博客中提出了一个问题:怎么结束一个定时循环执行的线程,并给出了一个解决方案,但是又出现了一个问题,详细去参考上一篇博客

  然后出去撒了个尿,突然脑子里出现了一个想法(看来工作和思考久了,出去走走,哪怕是去撒个尿,都可能尿出火花,所以工作和学习的时常根本就不等同于效率灵感不是在那里拼命工作、想就能出来的),需要结合上上篇博客:关于FreeOnTerminate的知识

上面所给出的第一种解决方案:

  线程(Execute)在执行定时循环;然后先让 DestroyAThread设置 Terminated属性,通知线程去结束执行、释放资源;然后在线程结束执行、释放资源之后再去通知DestroyAThread,再由DestroyAThread来显式调用线程的 Free方法来释放线程

所以结合 FreeOnTerminate的作用,复习一下:

  类 Create 了就要 Free;

  但 TThread(的子类) 有特殊性, 很多时候我们不能确定新建的线程什么时候执行完(也就是什么时候该释放);   

  如果线程执行完毕自己知道释放就好了, 所以 TThread 给了一个布尔属性 FreeOnTerminate, 如果为 True, 线程执行完毕后就会自释放.

进行改造:

  首先在线程的Execute方法里面将 FreeOnTerminate设置为True,然后进行自己的定时循环执行;然后DestroyAThread设置Terminated属性,通知线程去结束执行、释放资源;然后在线程结束执行、释放资源之后,因为FreeOnTerminate设置为True了,所以就不要再通知 DestroyAThread,自己在释放完资源、结束执行之后,就会自释放。

  同样DestroyAThread设置Terminated属性之后,就可以直接退出,因为不需要在DestroyAThread里面显式释放线程。

  同样也就不需要线程再有 CanFree这种通知别人来释放它的属性了,所以也能简化线程类的设计(在面向对象的程序设计中一个原则就是:类尽可能小,所以那些能不需要的属性、方法就不要去定义和使用,把冗余的属性和方法一定要去掉……)

所以新的代码可以是这样的

Execute方法:

procedure TDoSomeThingThread.Execute;
var
i: Integer;
begin
inherited;
FreeOnTerminate:= True;
//CanFree := False; //不再需要 CanFree这样的属性了,也就简化了线程类的设计
try
while not Self.Terminated do
begin
........
{
在这里编写该线程具体所要做的事情的代码逻辑,
如果这里面还是要循环执行一些任务,
最好能在每次循环的时候也都再去检查一下Terminated的值
如果是True就结束循环,
就是保证在较短的事件内不断检查 Terminated标志,保证能够及时退出
}
........
Sleep(5);
Application.ProcessMessages;
end;
finally
//CanFree := True; //不再需要 CanFree这样的属性了,也就简化了线程类的设计
{在这里将线程申请的资源进行释放……后续操作}
end;
end;

  

DestroyAThread方法:

procedure DestroyAThread(testThread: TDoSomeThingThread); stdcall;
var
  itime: Cardinal;
begin
  if Assigned(testThread) then
  begin
    testThread.Terminate;      //在这里将testThread的 Terminated属性设置为True {
这里就只需要通过Terminate方法将线程的Terminated设置为True,
去通知线程结束就行了,
不需要关心线程的释放问题,因为线程会自己释放
}
  end; //这个方案中就不需要使用Free方法去显式释放线程资源了,因为线程自己会在执行结束后自动释放
end;

  

Delphi中怎么结束线程(这个线程是定时执行的)(方案二)的更多相关文章

  1. Delphi中线程类TThread实现多线程编程2---事件、临界区、Synchronize、WaitFor……

    接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event) 事件(Event)与De ...

  2. Delphi中线程类TThread实现多线程编程1---构造、析构……

    参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832053.html Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大 ...

  3. 转发 Delphi中线程类TThread 实现多线程编程

    Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchr ...

  4. Delphi中的线程类 - TThread详解

    Delphi中的线程类 - TThread详解 2011年06月27日 星期一 20:28 Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本 ...

  5. Delphi中的线程类(转)

    Delphi中的线程类 (转) Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对 TThread类的几个成员作一简单介绍,再说明一下 ...

  6. 在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程!(更好的管理异常)

    在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程! 如果直接使用Win32的API函数CreateThread()创建多个线程,也是可以创建的.但 ...

  7. C# 多线程是否结束可通过线程池可以判断

    C# ManualResetEvent信号状态判断线程池是否结束  这是一段重要的代码,小猪两个小时的研究成果,记下来备查. using System; using System.Collection ...

  8. VC中利用多线程技术实现线程之间的通信

    当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...

  9. [读书心得] .NET中 类型,对象,线程栈,托管堆在运行时的关系

    .NET中 类型,对象,线程栈,托管堆 在运行时的关系 The Relationship at Run Time between Types,Objects,A Thread's Stack,and ...

随机推荐

  1. Unity3D获取Andorid设备返回键,主页键等功能

    在Unity开发中捕捉Android的常用事件其实很简单 在新建的脚本文件中就加入: 比如: // 返回键 if ( Application.platform == RuntimePlatform.A ...

  2. ReLU 和sigmoid 函数对比以及droupout

    参考知乎的讨论:https://www.zhihu.com/question/29021768 1.计算简单,反向传播时涉及除法,sigmod求导要比Relu复杂: 2.对于深层网络,sigmod反向 ...

  3. Ubuntu 虚拟机空间不足增加空间笔记

    一开始给虚拟机加空间以为只是需要在虚拟机设置里面添加就行,后面发现还得重新在虚拟机内部增加. 链接: http://pan.baidu.com/s/1c2uVcCo 密码: xid8 这只是第一步,共 ...

  4. python入门教程链接

    python安装 选择 2.7及以上版本 linux: 一般都自带 windows: https://www.python.org/downloads/windows/ mac os: https:/ ...

  5. Genymotion自动化启动

      一.启动方式 命令行: player.exe --vm-name [模拟器名称]   例子: "D:\Program files\Genymobile\Genymotion\player ...

  6. 基于用户相似性的协同过滤——Python实现

    代码基本来自项亮的<推荐系统实践>,把书上的伪代码具体实现,还参考了https://www.douban.com/note/336280497/ 还可以加入对用户相似性的归一化操作,效果会 ...

  7. sed使用的并不是完全的正则表达式

    经过实验发现,命令sed 's/pattern/replacement/' file中,pattern使用的并不是完全的正则表达式,而如果想使用正则表达式,需要使用sed命令的 -r 选项: sed ...

  8. BIOS开启虚拟化

    启动时根据提示按del 键按 F10 键以配置 BIOS使用箭头键滚动到“System Configuration”选择“Virtualization Technology”,然后按 Enter 键选 ...

  9. 【leetcode】Symmetric Tree

    Symmetric Tree Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its ...

  10. C# 中的virtural和abstract

    一. Virtual 方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual 的使用有两种情况: 1.在基类中定义了virtual方法,但是派生类中没有重写该虚方法,那么在对派生类 ...