• 关于线程的停止、挂起、退出(修改)


    原来的实现:http://blog.csdn.net/jankercsdn/article/details/8874469 有许多不完善的地方,使用中进行了一些改动和完善,

    unit uHardWorkThread;
    
    interface
    
    uses
      Windows, Messages, Classes, SysUtils, SyncObjs;
    
    const
      WM_QUIT_HARD_THREAD = WM_USER + 305;  //退出线程
    
    type
      THardWorkThread = class(TThread)
      private
        FMsgHandle:THandle;                               //消息目的窗口句柄
        FErrorCount:Integer;                              //连续错误次数
        FIsWorking:boolean;                               //是否正在工作
        FIsSuspending:Boolean;                            //是否正在挂起
        FQuitEvent:TEvent;                                //退出线程事件
        FRunEvent:TEvent;                                 //运行事件,有信号表示运行
        FWorkCompletedEvent:TEvent;                       //工作完成事件, 有信号表示完成
        FPIsInterrupt:PBoolean;                           //中断
      protected
    
        function  WaitForWorkCompleted(const AWaitTime:Integer):Boolean;        //等待线程工作完成
        procedure SetupWorkCompleted(AWorkCompleted:Boolean);                   //设置线程工作状态
        procedure ImmediatelySuspend;                                           //立即挂起,一般继承子孙类内部用
        procedure Execute; override;
        procedure DoWorkProc(const APIsInterrupt:PBoolean); virtual; abstract;  //实际的工作过程(虚方法,子类必须实现)
      public
        constructor Create(AMsgHandle:THandle); virtual;                        //这个句柄注意,当消息目的窗体的Position变化时,窗体的Handle就变了(比如Dock窗体)
        destructor Destroy; override;
    
        procedure StartThread;                                                  //开始线程
        function  ExitThread(const AWaitTime:Integer):Boolean;                  //退出线程
        function  SuspendThread(const AWaitTime:Integer):Boolean;               //挂起线程
        procedure ResumeThread;                                                 //恢复线程
        property  MsgHandle:THandle read FMsgHandle write FMsgHandle;           //消息句柄
        property  ErrorCount:Integer read FErrorCount;
      end;
    
    implementation
    
    { THardWorkThread }
    
    constructor THardWorkThread.Create(AMsgHandle: THandle);
    begin
      inherited Create(True);
    
      FMsgHandle:=AMsgHandle;
    
      FQuitEvent:=TEvent.Create;
      FRunEvent:=TEvent.Create;
      FRunEvent.ResetEvent;
      FWorkCompletedEvent:=TEvent.Create;
      FWorkCompletedEvent.SetEvent;
      New(FPIsInterrupt);
      FPIsInterrupt^:=False;
    
      FErrorCount:=0;
      FIsWorking:=False;
      FIsSuspending:=True;
      //FreeOnTerminate:=True;  //不要自动释放
    end;
    
    destructor THardWorkThread.Destroy;
    begin
      Dispose(FPIsInterrupt);
      FWorkCompletedEvent.Free;
      FRunEvent.Free;
      FQuitEvent.Free;
    
      inherited;
    end;
    
    {
    procedure THardWorkThread.DoWorkProc;
    begin
    
    end;
    }
    procedure THardWorkThread.Execute;
    var
      Msg:TMsg;
    begin
      while True do
      begin
        if PeekMessage(Msg,0,0,0,PM_REMOVE) then
        begin
          if Msg.message = WM_QUIT_HARD_THREAD then
          begin
            FQuitEvent.SetEvent;
            Break;
          end;
        end;
    
        if FPIsInterrupt^ then
        begin
          Continue;
        end;
        //等待运行
        FIsSuspending := True;
        FRunEvent.WaitFor(INFINITE);
        FIsSuspending := False;
        //退出时,如果线程挂起,则要恢复线程,然后退出
        if PeekMessage(Msg,0,0,0,PM_NOREMOVE) then
        begin
          if Msg.message = WM_QUIT_HARD_THREAD then
            Continue;
        end;
    
        if FPIsInterrupt^ then
        begin
          Continue;
        end;
    
        SetupWorkCompleted(False);          //开始工作
        try
          DoWorkProc(FPIsInterrupt);
        finally
          SetupWorkCompleted(True);        //完成工作
        end;
    
        Sleep(100);
      end;
    end;
    
    function THardWorkThread.ExitThread(const AWaitTime: Integer): Boolean;
    begin
      Result:=True;
      FPIsInterrupt^:=True;
      PostThreadMessage(ThreadID,WM_QUIT_HARD_THREAD,0,0);
      if FIsSuspending then
        ResumeThread;
      //PostThreadMessage(ThreadID,WM_QUIT_HARD_THREAD,0,0);
      if FQuitEvent.WaitFor(AWaitTime) = wrTimeOut then
        Result:=False;
    end;
    
    procedure THardWorkThread.ImmediatelySuspend;
    begin
      FRunEvent.ResetEvent;
      //FIsSuspending := True;
    end;
    
    procedure THardWorkThread.ResumeThread;
    begin
      FRunEvent.SetEvent;
      //FIsSuspending := False;
    end;
    
    procedure THardWorkThread.SetupWorkCompleted(AWorkCompleted: Boolean);
    begin
      FIsWorking:=not AWorkCompleted;
      if AWorkCompleted then
      begin
        FWorkCompletedEvent.SetEvent;
      end
      else
      begin
        FWorkCompletedEvent.ResetEvent;
      end;
    end;
    
    procedure THardWorkThread.StartThread;
    begin
      Start;
    end;
    
    function THardWorkThread.SuspendThread(const AWaitTime: Integer): Boolean;
    begin
      Result:=False;
      if FIsSuspending then
      begin
        Result:=True;
      end
      else
      begin
        if WaitForWorkCompleted(AWaitTime) then
        begin
          FRunEvent.ResetEvent;
          FIsSuspending:=True;
          Result:=True;
        end;
      end;
    end;
    
    function THardWorkThread.WaitForWorkCompleted(const AWaitTime: Integer): Boolean;
    begin
      Result:=True;
      if FIsWorking then
        Result:=FWorkCompletedEvent.WaitFor(AWaitTime) = wrSignaled;
    end;
    
    end.


  • 相关阅读:
    CDH 2、Cloudera Manager的安装
    204 01 Android 零基础入门 03 Java常用工具类 04 Java集合 04 Map集合 01 Map概述
    203 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 07 删除宠物猫信息数据(引入泛型知识点)
    202 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 06 查找宠物猫信息数据
    201 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 05 添加重复的宠物猫信息数据
    200 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 04 添加和显式宠物猫信息
    199 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 03 宠物猫信息管理概述
    198 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 02 案例:在集合中插入字符串
    197 01 Android 零基础入门 03 Java常用工具类 04 Java集合 03 Set集合 01 Set概述
    196 01 Android 零基础入门 03 Java常用工具类 04 Java集合 02 List集合 05 案例:公告的删除和修改
  • 原文地址:https://www.cnblogs.com/jankerxp/p/7774030.html
Copyright © 2020-2023  润新知