找回密码
 立即注册
首页 资源区 代码 mormot.core.threads--TSynBackgroundThread

mormot.core.threads--TSynBackgroundThread

茅香馨 4 天前
mormot.core.threads--TSynBackgroundThread

在mORMot 2框架中,TSynBackgroundThreadEvent、TSynBackgroundThreadMethod、TSynBackgroundThreadProcedure、TSynBackgroundThreadProcess和 TSynBackgroundTimer这几个类虽然都涉及到后台线程的执行,但它们各自有不同的用途和设计目标。以下是对这些类之间差异的概述:

  • TSynBackgroundThreadEvent

    • 这个类可能设计用于执行与事件相关的回调函数。它可能封装了一个事件处理机制,允许您在后台线程中响应特定的事件。
    • 回调函数的签名可能包括一个事件发送者(Sender)参数,以及可能的其他参数,用于传递事件相关的数据。
    • 由于名称中包含“Event”,它可能特别适用于事件驱动的场景。

  • TSynBackgroundThreadMethod

    • 这个类设计用于执行标准的 TThreadMethod类型的回调,即无参数且返回 Void的过程。
    • 它提供了一种在后台线程中执行这些回调的简便方式,使得与Delphi标准线程库兼容的代码可以轻松地与mORMot 2框架集成。
    • 由于 TThreadMethod是Delphi中用于线程方法的标准类型,因此这个类可能特别适用于需要这种兼容性的场景。

  • TSynBackgroundThreadProcedure

    • 这个类可能设计用于执行简单的无参数过程(procedure)回调,而不是一个对象方法或 TThreadMethod。
    • 它与 TSynBackgroundThreadMethod类似,但可能更加专注于那些不需要传递额外参数的过程。
    • 使用这个类可以使代码更加简洁,特别是当回调不需要访问任何外部状态或参数时。

  • TSynBackgroundThreadProcess

    • 这个类可能是一个更通用的后台线程处理类,它可能提供了执行周期性任务或长时间运行任务的能力。
    • 它可能封装了线程创建、启动、暂停、恢复和终止的逻辑,以及任务调度的机制。
    • 与其他几个类相比,TSynBackgroundThreadProcess可能更加灵活和强大,适用于需要复杂任务调度的场景。

  • TSynBackgroundTimer

    • 这个类专门设计用于在后台线程中执行定时任务。
    • 它可能内部维护了一个或多个定时器,允许您安排任务在指定的时间间隔后执行。
    • TSynBackgroundTimer可能还提供了向定时任务传递消息或参数的能力,以及查询任务状态和执行结果的方法。
    • 它特别适用于需要定时执行任务的场景,如心跳检测、定时轮询等。

上述描述是基于对类名的一般性推断和假设。实际上,mORMot 2框架中的这些类的具体实现和用途可能有所不同。因此,如果您正在使用mORMot 2框架,并且想要了解这些类的确切差异和用法,最好的做法是查阅mORMot 2的官方文档或源代码。这将为您提供关于这些类的详细信息和示例代码,帮助您更好地理解和使用它们。
TSynBackgroundThreadMethodAbstrac 定义
  1. /// TSynBackgroundThreadAbstract 进程的状态机状态
  2. TSynBackgroundThreadProcessStep = (
  3.     flagIdle,           // 空闲状态
  4.     flagStarted,        // 已启动状态
  5.     flagFinished,       // 已完成状态
  6.     flagDestroying);    // 正在销毁状态
  7. /// TSynBackgroundThreadAbstract进程的状态机状态集合
  8. TSynBackgroundThreadProcessSteps = set of TSynBackgroundThreadProcessStep;
  9. /// 抽象TThread类,能够在其自己的执行内容中运行一个方法
  10. // - 典型用途是作为处理数据或远程访问的后台线程,
  11. // 同时UI通过循环运行OnIdle事件保持响应:
  12. // 例如,查看mormot.rest.client.pas单元中TRestClientUri.OnIdle是如何处理此事件的
  13. // - 您不应直接使用此类,而应继承它并重写Process方法,
  14. // 或者使用TSynBackgroundThreadEvent/TSynBackgroundThreadMethod,
  15. // 并提供一个更加方便的回调函数
  16. TSynBackgroundThreadMethodAbstract = class(TSynBackgroundThreadAbstract)
  17. protected
  18.     fPendingProcessLock: TLightLock;     // 对fPendingProcessFlag的原子访问
  19.     fCallerEvent: TSynEvent;             // 调用者事件
  20.     fParam: pointer;                     // 参数指针
  21.     fCallerThreadID: TThreadID;          // 调用者线程ID
  22.     fBackgroundException: Exception;     // 后台线程异常
  23.     fOnIdle: TOnIdleSynBackgroundThread; // 空闲时回调事件
  24.     fOnBeforeProcess: TOnNotifyThread;   // 处理前通知回调
  25.     fOnAfterProcess: TOnNotifyThread;    // 处理后通知回调
  26.     fPendingProcessFlag: TSynBackgroundThreadProcessStep;        // 待处理标志
  27.     procedure ExecuteLoop; override;     // 重写执行循环
  28.     function OnIdleProcessNotify(var start: Int64): Int64;       // 空闲处理通知,返回已用毫秒数
  29.     function GetOnIdleBackgroundThreadActive: boolean;           // 获取OnIdle事件是否激活
  30.     function GetPendingProcess: TSynBackgroundThreadProcessStep; // 获取待处理状态
  31.     procedure SetPendingProcess(State: TSynBackgroundThreadProcessStep); // 设置待处理状态
  32.     // 如果获取成功则返回flagIdle,如果已终止则返回flagDestroying
  33.     function AcquireThread: TSynBackgroundThreadProcessStep;
  34.     procedure WaitForFinished(start: Int64; const onmainthreadidle: TNotifyEvent); // 等待完成
  35.   
  36.     /// 当fProcessParams<>nil且fEvent被通知时,由Execute方法调用
  37.     procedure Process; virtual; abstract;                           // 抽象方法,需在子类中实现
  38. public
  39.     /// 初始化线程
  40.     // - 如果aOnIdle未设置(即等于nil),它将简单地等待后台进程完成,直到RunAndWait()返回
  41.     // - 您可以定义一些回调来嵌套线程执行,例如,分配给TRestServer.BeginCurrentThread/EndCurrentThread
  42.     constructor Create(const aOnIdle: TOnIdleSynBackgroundThread;
  43.       const aThreadName: RawUtf8;
  44.       const OnBeforeExecute: TOnNotifyThread = nil;
  45.       const OnAfterExecute: TOnNotifyThread = nil); reintroduce;
  46.   
  47.     /// 销毁线程
  48.     destructor Destroy; override;
  49.   
  50.     /// 在后台线程中异步启动Process抽象方法
  51.     // - 等待进程完成,同时调用OnIdle()回调
  52.     // - 在后台线程中引发的任何异常都将在调用者线程中转换
  53.     // - 如果self未设置,或者从当前正在处理的同一线程调用(以避免OnIdle()回调中的竞态条件),则返回false
  54.     // - 当后台进程完成时返回true
  55.     // - OpaqueParam将用于指定后台进程线程安全的内容
  56.     // - 此方法是线程安全的,即它将等待另一个线程已经启动的任何进程:
  57.     // 您可以从任何线程调用此方法,即使其主要用途是从主UI线程调用
  58.     function RunAndWait(OpaqueParam: pointer): boolean;
  59.   
  60.     /// 设置一个回调事件,在远程阻塞过程期间循环执行,
  61.     // 例如,在长时间请求期间刷新UI
  62.     // - 您可以为此属性分配一个回调,例如调用Application.ProcessMessages,
  63.     // 以在后台线程中执行远程请求,但让UI仍然具有响应性:
  64.     // mORMotUILogin.pas中的TLoginForm.OnIdleProcess和OnIdleProcessForm方法将符合此属性的预期
  65.     // - 如果OnIdle未设置(即等于nil),它将简单地等待后台进程完成,直到RunAndWait()返回
  66.     property OnIdle: TOnIdleSynBackgroundThread   read fOnIdle write fOnIdle;
  67.   
  68.     /// 如果后台线程处于活动状态,并且在处理过程中调用了OnIdle事件,则为TRUE
  69.     // - 例如,用于确保没有来自用户界面消息的重新进入
  70.     property OnIdleBackgroundThreadActive: boolean read GetOnIdleBackgroundThreadActive;
  71.   
  72.     /// 在Execute中每次处理之前触发的可选回调事件
  73.     property OnBeforeProcess: TOnNotifyThread   read fOnBeforeProcess write fOnBeforeProcess;
  74.   
  75.     /// 在Execute中每次处理之后触发的可选回调事件
  76.     property OnAfterProcess: TOnNotifyThread    read fOnAfterProcess write fOnAfterProcess;
  77. end;
复制代码
TSynBackgroundThreadEvent,TSynBackgroundThreadMethod,TSynBackgroundThreadProcedure,TSynBackgroundThreadProcess
TSynBackgroundThreadEvent 定义
  1. /// 由 TSynBackgroundThreadEvent 调用的后台进程方法
  2. // - 当执行Process虚拟方法时,将提供RunAndWait()方法中指定的OpaqueParam参数
  3. TOnProcessSynBackgroundThread = procedure(Sender: TSynBackgroundThreadEvent;
  4.     ProcessOpaqueParam: pointer) of object;
  5. /// 允许后台线程处理方法回调
  6. TSynBackgroundThreadEvent = class(TSynBackgroundThreadMethodAbstract)
  7. protected
  8.     fOnProcess: TOnProcessSynBackgroundThread; // 回调事件
  9.   
  10.     /// 仅调用OnProcess处理程序
  11.     procedure Process; override; // 重写Process方法
  12. public
  13.     /// 初始化线程
  14.     // - 如果aOnIdle未设置(即等于nil),它将简单地等待后台进程完成,直到RunAndWait()返回
  15.     constructor Create(const aOnProcess: TOnProcessSynBackgroundThread;
  16.       const aOnIdle: TOnIdleSynBackgroundThread;
  17.       const aThreadName: RawUtf8); reintroduce; // 重引入构造函数
  18.   
  19.     /// 提供一个方法处理程序,在后台线程中执行
  20.     // - 由RunAndWait()方法触发 - 该方法将等待直到完成
  21.     // - 这里将提供RunAndWait()方法中指定的OpaqueParam
  22.     property OnProcess: TOnProcessSynBackgroundThread
  23.       read fOnProcess write fOnProcess; // OnProcess属性,用于访问fOnProcess字段
  24. end;
复制代码
TSynBackgroundThreadMethod 定义
  1. /// 允许后台线程处理可变的TThreadMethod回调
  2. TSynBackgroundThreadMethod = class(TSynBackgroundThreadMethodAbstract)
  3. protected
  4.     /// 仅调用RunAndWait()方法中提供的TThreadMethod
  5.     procedure Process; override; // 重写Process方法
  6. public
  7.     /// 运行一次提供的TThreadMethod回调
  8.     // - 使用此方法,而不是继承的RunAndWait()
  9.     procedure RunAndWait(Method: TThreadMethod); reintroduce; // 重引入RunAndWait方法
  10. end;
复制代码
TSynBackgroundThreadProcedure 定义
  1. /// 由 TSynBackgroundThreadProcedure 调用的后台进程过程
  2. // - 当执行Process虚拟方法时,将提供RunAndWait()方法中指定的OpaqueParam参数
  3. TOnProcessSynBackgroundThreadProc = procedure(ProcessOpaqueParam: pointer);
  4. /// 允许后台线程处理过程回调
  5. TSynBackgroundThreadProcedure = class(TSynBackgroundThreadMethodAbstract)
  6. protected
  7.     fOnProcess: TOnProcessSynBackgroundThreadProc; // 回调过程
  8.     /// 仅调用OnProcess处理程序
  9.     procedure Process; override; // 重写Process方法
  10. public
  11.     /// 初始化线程
  12.     // - 如果aOnIdle未设置(即等于nil),它将简单地等待后台进程完成,直到RunAndWait()返回
  13.     constructor Create(aOnProcess       : TOnProcessSynBackgroundThreadProc;
  14.                        const aOnIdle    : TOnIdleSynBackgroundThread;
  15.                        const aThreadName: RawUtf8); reintroduce; // 重引入构造函数
  16.   
  17.     /// 提供一个过程处理程序,在后台线程中执行
  18.     // - 由RunAndWait()方法触发 - 该方法将等待直到完成
  19.     // - 这里将提供RunAndWait()方法中指定的OpaqueParam
  20.     property OnProcess: TOnProcessSynBackgroundThreadProc
  21.       read fOnProcess write fOnProcess; // OnProcess属性,用于访问fOnProcess字段
  22. end;
复制代码
TSynBackgroundThreadProcess 定义
  1. type
  2.   // TSynBackgroundThreadProcess 类声明(稍后定义)
  3.   TSynBackgroundThreadProcess = class;
  4.   /// 由 TSynBackgroundThreadProcess 定期执行的事件回调
  5.   TOnSynBackgroundThreadProcess = procedure(Sender: TSynBackgroundThreadProcess) of object;
  6.   /// 能够以给定周期运行方法的 TThread 类
  7.   TSynBackgroundThreadProcess = class(TSynBackgroundThreadAbstract)
  8.   protected
  9.     fOnProcess: TOnSynBackgroundThreadProcess; // 定期执行的方法回调
  10.     fOnException: TNotifyEvent; // 当 OnProcess 引发异常时执行的事件回调
  11.     fOnProcessMS: cardinal; // 定期执行任务的时间间隔(毫秒)
  12.     fStats: TSynMonitor; // 处理统计信息
  13.     procedure ExecuteLoop; override; // 重写执行循环
  14.   public
  15.     /// 初始化线程以进行周期性任务处理
  16.     // - 当 ProcessEvent.SetEvent 被调用或自上次处理以来过去了 aOnProcessMS 毫秒时,将调用 aOnProcess
  17.     // - 如果 aOnProcessMS 为 0,则等待直到 ProcessEvent.SetEvent 被调用
  18.     // - 您可以定义一些回调来嵌套线程执行,例如,分配给 TRestServer.BeginCurrentThread/EndCurrentThread
  19.     constructor Create(
  20.         const aThreadName     : RawUtf8;
  21.         const aOnProcess      : TOnSynBackgroundThreadProcess;
  22.         aOnProcessMS          : cardinal;
  23.         const aOnBeforeExecute: TOnNotifyThread = nil;
  24.         const aOnAfterExecute : TOnNotifyThread = nil;
  25.         aStats                : TSynMonitorClass = nil;
  26.         CreateSuspended       : boolean = false); reintroduce; virtual;
  27.   
  28.     /// 终结线程并等待其结束
  29.     destructor Destroy; override;
  30.   
  31.     /// 访问周期性任务的实现事件
  32.     property OnProcess: TOnSynBackgroundThreadProcess
  33.       read fOnProcess;
  34.   
  35.     /// 当 OnProcess 引发异常时执行的事件回调
  36.     // - 提供的 Sender 参数是引发的异常实例
  37.     property OnException: TNotifyEvent
  38.       read fOnException write fOnException;
  39.   
  40.   published
  41.   
  42.     /// 访问周期性任务处理的延迟时间(毫秒)
  43.     property OnProcessMS: cardinal  read fOnProcessMS write fOnProcessMS;
  44.   
  45.     /// 处理统计信息
  46.     // - 如果在类构造函数中 aStats 为 nil,则可能为 nil
  47.     property Stats: TSynMonitor   read fStats;
  48.   end;
复制代码
TSynBackgroundTimer 定义
  1.   // TSynBackgroundTimer 类声明(稍后定义)
  2.   TSynBackgroundTimer = class;
  3.   /// 由 TSynBackgroundThreadProcess 定期执行的事件回调(特定于 TSynBackgroundTimer)
  4.   // - 如果此任务 FIFO 中没有挂起的消息,则 Msg 为 ''
  5.   // - 对于此任务 FIFO 中的每个挂起消息,都会设置 Msg
  6.   // - 在 mORMot 1 中,有一个 TWaitEvent 参数,现在已被移除
  7.   TOnSynBackgroundTimerProcess = procedure(Sender: TSynBackgroundTimer;
  8.     const Msg: RawUtf8) of object;
  9.   /// TSynBackgroundTimer 内部注册列表使用的记录类型
  10.   TSynBackgroundTimerTask = record
  11.     OnProcess: TOnSynBackgroundTimerProcess; // 处理任务的回调过程
  12.     Secs: cardinal; // 任务执行的间隔时间(秒)
  13.     NextTix: Int64; // 下一次执行任务的时间戳
  14.     Msg: TRawUtf8DynArray; // 与此任务关联的待处理消息队列
  15.     MsgSafe: TLightLock; // 保护 Msg[] 列表的轻量级锁
  16.   end;
  17.   /// 存储 TSynBackgroundTimer 内部注册列表的动态数组类型
  18.   TSynBackgroundTimerTaskDynArray = array of TSynBackgroundTimerTask;
  19.   /// 能够在后台线程中以定期的速度运行一个或多个任务的线程类
  20.   // - 例如,通过继承自 TRestBackgroundTimer 的 TRest.TimerEnable/TimerDisable 方法使用
  21.   // - 每个进程可以有自己的文本消息 FIFO 队列
  22.   // - 如果您期望更新某些 GUI,则应该使用 TTimer 组件(例如,周期为 200ms),
  23.   // 因为 TSynBackgroundTimer 将使用它自己的独立线程
  24.   TSynBackgroundTimer = class(TSynBackgroundThreadProcess)
  25.   protected
  26.     fTask: TSynBackgroundTimerTaskDynArray; // 内部任务列表
  27.     fTasks: TDynArrayLocked; // 任务列表的封装和同步访问
  28.     fProcessing: boolean; // 标记当前是否有任务正在处理
  29.     fProcessingCounter: integer; // 处理中的任务计数器(可能是内部使用)
  30.     procedure EverySecond(Sender: TSynBackgroundThreadProcess); // 每秒执行一次的回调,用于处理任务
  31.     function Find(const aProcess: TMethod): PtrInt; // 查找已注册的任务(内部使用)
  32.     function Add(const aOnProcess: TOnSynBackgroundTimerProcess;
  33.       const aMsg: RawUtf8; aExecuteNow: boolean): boolean; // 添加任务到内部列表
  34.   public
  35.     /// 初始化线程以进行周期性任务处理
  36.     // - 您可以定义一些回调来嵌套线程执行,例如,
  37.     // 分配给 TRestServer.BeginCurrentThread/EndCurrentThread,如 TRestBackgroundTimer.Create 所做
  38.     constructor Create(const aThreadName: RawUtf8;
  39.       const aOnBeforeExecute: TOnNotifyThread = nil;
  40.       aOnAfterExecute: TOnNotifyThread = nil;
  41.       aStats: TSynMonitorClass = nil;
  42.       aLogClass: TSynLogClass = nil); reintroduce; virtual;
  43.   
  44.     /// 销毁线程
  45.     destructor Destroy; override;
  46.     /// 为在固定秒数周期上运行的任务定义一个处理方法
  47.     // - 对于 mORMot 服务上的后台进程,请考虑使用 TRest 的
  48.     // TimerEnable/TimerDisable 方法及其关联的 BackgroundTimer 线程
  49.     procedure Enable(const aOnProcess: TOnSynBackgroundTimerProcess;
  50.       aOnProcessSecs: cardinal);
  51.   
  52.     /// 取消定义在固定秒数周期上运行的任务
  53.     // - aOnProcess 应通过之前的 Enable() 方法调用进行注册
  54.     // - 成功时返回 true,如果提供的任务未注册则返回 false
  55.     // - 对于 mORMot 服务上的后台进程,请考虑使用 TRestServer 的
  56.     // TimerEnable/TimerDisable 方法及其 TSynBackgroundTimer 线程
  57.     function Disable(const aOnProcess: TOnSynBackgroundTimerProcess): boolean;
  58.   
  59.     /// 在任务的下一次执行期间添加要处理的消息
  60.     // - 提供的消息将被添加到与 aOnProcess 关联的内部 FIFO 列表中,
  61.     // 然后作为 aMsg 参数传递给每次调用
  62.     // - 如果 aExecuteNow 为 true,则不会等待下一个 aOnProcessSecs 的发生
  63.     // - aOnProcess 应通过之前的 Enable() 方法调用进行注册
  64.     // - 成功时返回 true,如果提供的任务未注册则返回 false
  65.     function EnQueue(const aOnProcess: TOnSynBackgroundTimerProcess;
  66.       const aMsg: RawUtf8; aExecuteNow: boolean = false): boolean; overload;
  67.   
  68.     /// 在任务的下一次执行期间添加要处理的消息(格式化版本)
  69.     // - ...(与上一个 EnQueue 重载类似,但允许格式化消息)
  70.     function EnQueue(const aOnProcess: TOnSynBackgroundTimerProcess;
  71.       const aMsgFmt: RawUtf8; const Args: array of const;
  72.       aExecuteNow: boolean = false): boolean; overload;
  73.   
  74.     /// 从处理列表中删除消息
  75.     // - 提供的消息将在与 aOnProcess 关联的内部 FIFO 列表中进行搜索,
  76.     // 如果找到则从列表中删除
  77.     // - aOnProcess 应通过之前的 Enable() 方法调用进行注册
  78.     // - 成功时返回 true,如果提供的消息未注册则返回 false
  79.     function DeQueue(const aOnProcess: TOnSynBackgroundTimerProcess;
  80.       const aMsg: RawUtf8): boolean;
  81.   
  82.     /// 不等待下一个 aOnProcessSecs 发生,立即执行任务
  83.     // - aOnProcess 应通过之前的 Enable() 方法调用进行注册
  84.     // - 成功时返回 true,如果提供的任务未注册则返回 false
  85.     function ExecuteNow(const aOnProcess: TOnSynBackgroundTimerProcess): boolean;
  86.   
  87.     /// 不等待下一个 aOnProcessSecs 发生,仅执行一次任务
  88.     // - aOnProcess 不需要通过之前的 Enable() 方法调用进行注册
  89.     function ExecuteOnce(const aOnProcess: TOnSynBackgroundTimerProcess): boolean;
  90.   
  91.     /// 等待直到没有后台任务正在处理
  92.     procedure WaitUntilNotProcessing(timeoutsecs: integer = 10);
  93.   
  94.     /// 对内部任务列表的低级访问
  95.     property Task: TSynBackgroundTimerTaskDynArray read fTask;
  96.   
  97.     /// 对内部任务列表封装和安全的低级访问
  98.     property Tasks: TDynArrayLocked read fTasks;
  99.   
  100.     /// 返回当前是否有任务正在处理
  101.     property Processing: boolean read fProcessing;
  102.   end;shi
复制代码
TSynBackgroundThreadEvent 例程代码
  1. uses
  2.   SysUtils, Classes, // 引入必要的单元
  3.   mormot.core.threads;
  4. type
  5.   TParams = record
  6.     Ti :integer;
  7.     Ts :string;
  8.   end;
  9.   { TForm1 }
  10.   TForm1 = class(TForm)
  11.     btThreadEvent :TButton;
  12.     Memo1 :TMemo;
  13.     procedure btThreadEventClick(Sender :TObject);
  14.   private
  15.   public
  16.     procedure OnBackgroundProcess1(Sender :TSynBackgroundThreadEvent; ProcessOpaqueParam :pointer);
  17.   end;   
  18. implementation
  19. procedure TForm1.OnBackgroundProcess1(Sender :TSynBackgroundThreadEvent; ProcessOpaqueParam :pointer);
  20. var
  21.   Call :^TParams absolute ProcessOpaqueParam; // pascal的妙
  22. begin
  23.   if Call = nil then
  24.     exit;
  25.   // 这里是后台处理的代码
  26.   WriteLn('Background process running with param: ', Call^.Ti);
  27.   LogDebug('Background process running with Tparam: T1=%d , T2=%s ', [Call^.Ti, Call^.Ts]);
  28. end;
  29. procedure TForm1.btThreadEventClick(Sender :TObject);
  30. var
  31.   BGThread :TSynBackgroundThreadEvent;
  32.   Param  : ^TParams ;
  33. var
  34.   MyProcessEvent :TOnProcessSynBackgroundThread;
  35. begin
  36.   New(Param);
  37.   Param^.Ti := 10; // 初始化参数
  38.    Param^.Ts := 'S99';
  39.   // 创建并启动后台线程事件
  40.   BGThread := TSynBackgroundThreadEvent.Create(@OnBackgroundProcess1, // 传递我们的处理过程
  41.     nil, // OnIdle回调,这里不使用
  42.     'MyBackgroundThreadEventDemo');
  43.   try
  44.     // 运行后台线程并等待完成
  45.     BGThread.RunAndWait(Param);
  46.     WriteLn('Background process finished. New param value: ', Param^.Ts);
  47.   finally
  48.     BGThread.Free;  // 销毁线程对象
  49.     Dispose(Param); // 释放参数内存
  50.   end;
  51. end;
复制代码
TSynBackgroundThreadMethod 例程代码
  1. interface
  2. uses
  3.   SysUtils, Classes,
  4.   mormot.core.threads;
  5. type
  6.   TForm1 = class(TForm)
  7.     btThreadMethod: TButton;
  8.     Memo1 :TMemo;
  9.     procedure btThreadMethodClick(Sender: TObject);
  10.   private
  11.   public
  12.     procedure ThreadMethod;
  13.   end;
  14. implementation  
  15. procedure TForm1.ThreadMethod;
  16. begin
  17.   // 这里是线程方法的代码
  18.   WriteLn('Thread method running in background');
  19.   // 模拟一些耗时操作
  20.   Sleep(1000);
  21. end;   
  22. procedure TForm1.btThreadMethodClick(Sender: TObject);
  23. var
  24.   BGThread: TSynBackgroundThreadMethod;
  25. begin
  26.   // 创建后台线程方法对象
  27.   BGThread := TSynBackgroundThreadMethod.Create(nil, 'MyBackgroundThreadMethodDemo');
  28.   try
  29.     // 注意:这里我们重写了RunAndWait方法,所以直接传递TThreadMethod
  30.     BGThread.RunAndWait(@ThreadMethod);
  31.   finally
  32.     BGThread.Free; // 销毁线程对象
  33.   end;
  34. end;  
复制代码
注意:上面的 TSynBackgroundThreadMethod示例中,我假设了 RunAndWait方法被重写以接受 TThreadMethod作为参数,但根据原始定义,这并不是直接支持的。通常,您会在 Process方法内部调用传入的 TThreadMethod。为了保持示例简单,我展示了如何可能使用它,但在实际应用中,您可能需要在 Process方法内部处理这一点。
TSynBackgroundThreadProcedure 例程代码
  1. uses
  2.   SysUtils, Classes,
  3.   mormot.core.threads;
  4. type
  5.   TParams = record
  6.     Ti :integer;
  7.     Ts :string;
  8.   end;
  9.   ....xl
  10. implementation
  11. procedure OnBackgroundProcedure(ProcessOpaqueParam :pointer);
  12. var
  13.   Call :^TParams absolute ProcessOpaqueParam;
  14. begin
  15.   if Call = nil then
  16.     exit;
  17.   // 这里是后台处理的代码
  18.   WriteLn('Background Procedure running with param: ', Call^.Ti);
  19.   LogDebug('Background Procedure running with Tparam: T1=%d , T2=%s ', [Call^.Ti, Call^.Ts]);
  20. end;
  21. procedure TForm1.btThreadProcedureClick(Sender: TObject);
  22. var
  23.   BGThread: TSynBackgroundThreadProcedure;
  24.   Param  : ^TParams ;
  25. begin
  26.   New(Param);
  27.   Param^.Ts := 'Hello, Background!';
  28.     Param^.Ti := 100;
  29.   // 创建并启动后台线程过程
  30.   BGThread := TSynBackgroundThreadProcedure.Create(
  31.     @OnBackgroundProcedure, // 传递我们的处理过程
  32.     nil, // OnIdle回调,这里不使用
  33.     'MyBackgroundThreadProcedureDemo'
  34.   );
  35.   try
  36.     // 运行后台线程并等待完成
  37.     BGThread.RunAndWait(Param);
  38.        WriteLn('Background Procedure finished. New param value: ', Param^.Ts);
  39.   finally
  40.     BGThread.Free; // 销毁线程对象
  41.     Dispose(Param); // 释放参数内存
  42.   end;
  43. end;
  44.    
复制代码
TSynBackgroundThreadProcess 例程代码
  1. uses
  2.   SysUtils, Classes, // 引入SysUtils和Classes单元以使用WriteLn和TThread等
  3.   mormot.core.threads;
  4. procedure TForm1.OnBackgroundProcess(Sender :TSynBackgroundThreadProcess);
  5. begin
  6.   WriteLn('Background Process running WriteLn ');
  7.   LogDebug('Background Process running ', []);
  8. end;
  9. procedure TForm1.btThreadProcessClick(Sender :TObject);
  10. var
  11.   BGThread :TSynBackgroundThreadProcess;
  12. begin
  13.   try
  14.       // 创建TSynBackgroundThreadProcess实例
  15.     BGThread := TSynBackgroundThreadProcess.Create('MyBackgroundThread', // 线程名称
  16.       @OnBackgroundProcess, // 周期性执行的方法
  17.       1000, // 周期时间,单位为毫秒
  18.       nil, // OnBeforeExecute回调,这里不使用
  19.       nil  // OnAfterExecute回调,这里不使用
  20.       // aStats和其他参数根据需要进行设置
  21.       );
  22.     try
  23.       // 启动线程(注意:在TSynBackgroundThreadProcess的构造函数中,
  24.       // 如果CreateSuspended参数为false,则线程将自动启动)
  25.       // 在这个例子中,我们假设CreateSuspended默认为false
  26.       // 等待一段时间以观察后台线程的行为
  27.       // 注意:在实际应用中,您可能不需要这样做,因为主线程可能会继续执行其他任务
  28.       Sleep(6000); // 等待6秒
  29.     finally
  30.       // 销毁线程对象(注意:在析构函数中,线程将尝试优雅地终止)
  31.       BGThread.Free;
  32.       // 等待线程真正结束(可选,但在这个例子中我们依赖析构函数的行为)
  33.     end;
  34.   except
  35.     on E :Exception do
  36.       WriteLn('Error: ' + E.Message);
  37.   end;
  38.   WriteLn('Program 结束.');
  39.   LogDebug('Background Process 结束 ', []);
  40. end;
  41. procedure TForm1.btThreadProcess2Click(Sender :TObject);
  42. begin
  43.   LogMSG('StartWatching');
  44.   G_BGThread := TSynBackgroundThreadProcess.Create('watchdog', @OnBackgroundProcess, 1000);
  45. end;  
复制代码
注意:在上面的示例中,我假设 TSynBackgroundThreadProcess的构造函数有一个 CreateSuspended参数(这在标准的 TThread构造函数中是存在的),但根据您提供的类定义,这个参数实际上并没有在 TSynBackgroundThreadProcess的构造函数中明确列出。如果 TSynBackgroundThreadProcess是自动启动线程的,那么您可能不需要显式调用任何启动方法。
TSynBackgroundTimer 例程代码
  1. uses
  2.   SysUtils, // 引入SysUtils单元以使用WriteLn
  3.   mormot.core.threads;
  4. procedure TForm1.OnBackgroundTimer(Sender :TSynBackgroundTimer; const Msg :RawUtf8);
  5. begin
  6.   WriteLn('Timer 0 called in background thread. Message: ' + Msg);
  7. end;
  8. procedure TForm1.OnBackgroundTimer2(Sender :TSynBackgroundTimer; const Msg :RawUtf8);
  9. begin
  10.   WriteLn('Timer 2 called in background thread. Message : ' + Msg);
  11. end;
  12. procedure TForm1.OnBackgroundTimer3(Sender :TSynBackgroundTimer; const Msg :RawUtf8);
  13. begin
  14.   WriteLn('Timer 3 called in background thread. Message : ' + Msg);
  15. end;
  16. procedure TForm1.OnBackgroundTimer5(Sender :TSynBackgroundTimer; const Msg :RawUtf8);
  17. begin
  18.   WriteLn('Timer 5 called in background thread. Message : ' + Msg);
  19. end;
  20. procedure TForm1.btThreadTimerClick(Sender :TObject);
  21. var
  22.   Timer :TSynBackgroundTimer;
  23. begin
  24.   try
  25.      // 创建TSynBackgroundTimer实例
  26.     Timer := TSynBackgroundTimer.Create('MyBackgroundTimer' // 线程名称
  27.       // 其他参数根据需要进行设置,这里省略了OnBeforeExecute、OnAfterExecute、aStats和aLogClass
  28.       );
  29.     try
  30.       // 启用一个周期性任务,每2秒执行一次
  31.       Timer.Enable(@OnBackgroundTimer2, 2);
  32.       // 后面动作都要用同一个  OnBackgroundTimer2  这点很重要
  33.       // 向任务队列添加消息,并请求立即执行(尽管在这个上下文中,立即执行可能不会立即发生)
  34.       Timer.EnQueue(@OnBackgroundTimer2, 'Hello from background timer!', True);
  35.       // 等待一段时间以观察后台定时器的行为
  36.       // 注意:在实际应用中,您可能不需要这样做,因为主线程可能会继续执行其他任务
  37.       // Sleep(10000); // 等待10秒
  38.       // Timer.ExecuteOnce(@OnBackgroundTimer2);
  39.       //Timer.ExecuteNow(@OnBackgroundTimer2);
  40.       Sleep(10000); // 等待10秒
  41.       // 禁用周期性任务(在这个示例中我们不会禁用它,但展示了如何禁用)
  42.       // Timer.Disable(@MyTimerProcess2);
  43.     finally
  44.       // 销毁TSynBackgroundTimer实例(注意:在实际应用中,您可能希望等待所有后台任务完成后再销毁定时器)
  45.       // 但在这个简单示例中,我们立即销毁它
  46.       Timer.Free;
  47.       // 由于我们立即销毁了定时器,并且主线程继续执行(尽管在这个示例中被Sleep阻塞了),
  48.       // 因此后台线程可能没有机会执行更多的回调。
  49.       // 在实际应用中,您应该确保在销毁定时器之前给后台线程足够的时间来完成其工作。
  50.     end;  
  51.   except
  52.     on E :Exception do
  53.       WriteLn('Error: ' + E.Message);
  54.   end;
  55.   WriteLn('Program ended.');
  56. end;  
复制代码
在上面的 TSynBackgroundTimer示例中,我展示了如何创建定时器、启用周期性任务、向任务队列添加消息,并等待一段时间以观察定时器的行为。请注意,由于我们调用了 Sleep并且立即销毁了定时器,因此后台线程可能没有机会执行更多的回调。在实际应用中,您应该确保在销毁定时器之前给后台线程足够的时间来完成其工作,或者调用 Timer.WaitUntilNotProcessing(如果该类提供了这样的方法)来等待所有后台任务完成。然而,根据提供的类定义,TSynBackgroundTimer并没有直接提供 WaitUntilNotProcessing方法,所以您可能需要实现自己的同步机制来达到这个目的。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册