zoukankan      html  css  js  c++  java
  • 关于线程的停止、挂起、退出(修改)

    原来的实现: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.


  • 相关阅读:
    BZOJ 2212/BZOJ 3702
    BZOJ 4761 Cow Navigation
    BZOJ 3209 花神的数论题
    BZOJ 4760 Hoof, Paper, Scissors
    BZOJ 3620 似乎在梦中见过的样子
    BZOJ 3940 Censoring
    BZOJ 3942 Censoring
    BZOJ 3571 画框
    BZOJ 1937 最小生成树
    BZOJ 1058 报表统计
  • 原文地址:https://www.cnblogs.com/jankerxp/p/7774030.html
Copyright © 2011-2022 走看看