Delphi中怎么结束线程(这个线程是定时执行的)(方案二)

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

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

  

时间: 2024-11-07 20:39:52

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

Struts2框架中书写XML配置文件时能添加提示技巧(方案二)

1.  先在/工程名/WebRoot/WEB-INF/lib/struts2-core-2.1.8.jar中找到struts-2.1.dtd文件. 2.  在Myeclipse8.6-->Window-->Preferences 3.  在搜索框输入xml文件,找到XMLCatalog,单击XML Catalog出现如上页面,之后单击Add按钮,出现如下图: 4.  在Location中选择FileSystem,选择struts-2.1.dtd文件的位置,如果这个文件在工程里面,可以使用Wor

Delphi中线程类TThread 实现多线程编程

作者:Rogee出处:Http://Rogee.cnblogs.com/心得:BLOG是什么,它是一个记录学习过程的东西 Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchronize的用法就完了.然而这并不是多线程编程的全部,我写此文的目的在于对此作一个补充. 线程本质上是进程中一段并发运行的代码.一个进程至少有一个线程,即所谓的主线程.同时还可以

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

在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程! 如果直接使用Win32的API函数CreateThread()创建多个线程,也是可以创建的.但是,你应该明白,在每个线程中动态分配和销毁内存块,是需要同步保护的.Delphi语言中有一个在使用多线程环境下至关重要的全局变量IsMultiThread,系统在进行内存分配的时候,根据IsMultiThread变量值判断当前是否使用在多线程环境下,如果该变量为True,哪么,系统在分配和销毁内存的

Delphi中线程类TThread实现多线程编程(线程同步技术、Synchronize、WaitFor……)

接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event)与Delphi中的事件有所不同.从本质上讲,Event其实就相当于一个全局的布尔变量.它有两个赋值操作:Set和ReSet,相当于把它设置为 True或False.而检查它的值是通过WaitFor操作进行.对应在Windows平台上,是三个API函数:SetEvent.ResetEvent.WaitForSignalObje

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

文章来源:[url]http://www.programfan.com/article/showarticle.asp?id=2951[/url] 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.

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

C# ManualResetEvent信号状态判断线程池是否结束 这是一段重要的代码,小猪两个小时的研究成果,记下来备查. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace 线程池判断结束综合演示 { class Program { public static int iCount = 0; public s

[转]C# 多线程是否结束可通过线程池可以判断

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading; namespace 线程池判断结束综合演示{    class Program    {        public static int iCount = 0;         public static int MaxCount = 10;//允许线程池中运行最多10个线程     

python中socket、进程、线程、协程、池的创建方式

一.TCP-socket 服务端: import socket tcp_sk = socket.socket() tcp_sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) tcp_sk.bind(('127.0.0.1',8000)) tcp_sk.listen() conn,addr = tcp_sk.accept() conn.send('你好'.encode('utf-8')) print(conn.recv(1024).deco

Python程序中的线程操作(线程池)-concurrent模块

目录 Python程序中的线程操作(线程池)-concurrent模块 一.Python标准模块--concurrent.futures 二.介绍 三.基本方法 四.ProcessPoolExecutor 五.ThreadPoolExecutor 六.map的用法 七.回调函数 Python程序中的线程操作(线程池)-concurrent模块 一.Python标准模块--concurrent.futures 官方文档:https://docs.python.org/dev/library/con