mormot.core.threads.pas unit

来源:https://www.cnblogs.com/hieroly/p/18241282
-Advertisement-
Play Games

介紹: 在當今數字化時代,網路上的信息量龐大,如何使自己的網站在搜索引擎中脫穎而出成為了每個網站管理員都面臨的挑戰。網頁的原創度不僅能提升用戶體驗,還有利於搜索引擎排名。本文將介紹如何利用Coz API來重寫課件PPT網的網頁標題和正文內容,以增加網頁的原創度。 Coz API簡介: Coz是位元組出 ...


mormot.core.threads.pas unit 中文翻譯

Purpose: Framework Core Multi-Threading Support
- this unit is a part of the Open Source Synopse mORMot framework 2, licensed under a MPL/GPL/LGPL three license - see LICENSE.md

目的:框架核心多線程支持

  • 本單元是開源Synopse mORMot框架2的一部分,根據MPL/GPL/LGPL三重許可進行許可-參見LICENSE.md

1.1. Units used in the mormot.core.threads unit (在mormot.core.threads單元中使用的單元)

Unit Name Description
mormot.core.base Framework Core Shared Types and RTL-like Functions 框架核心共用類型和類似RTL的函數
mormot.core.buffers Framework Core Low-Level Memory Buffer Process 框架核心低級記憶體緩衝區處理
mormot.core.data Framework Core Low-Level Data Processing Functions 框架核心低級數據處理函數
mormot.core.json Framework Core Low-Level JSON Processing 框架核心低級JSON處理
mormot.core.log Framework Core Logging 框架核心日誌記錄
mormot.core.os Framework Core Low-Level Wrappers to the Operating-System API 框架核心對操作系統API的低級包裝器
mormot.core.perf Framework Core Performance and Monitoring Classes 框架核心性能和監視類
mormot.core.rtti Framework Core Low-Level Cross-Compiler RTTI Definitions 框架核心低級跨編譯器RTTI定義
mormot.core.text Framework Core Low-Level Text Processing 框架核心低級文本處理
mormot.core.unicode Framework Core Low-Level Unicode UTF-8 UTF-16 Ansi Conversion 框架核心低級Unicode UTF-8 UTF-16 Ansi轉換
mormot.core.variants Framework Core Low-Level Variants / TDocVariant process 框架核心低級變數/TDocVariant處理

1.2. mormot.core.threads class hierarchy

TSynThread
TSynThreadPoolWorkThread
TNotifiedThreadTLoggedThread
TLoggedWorkThreadTThreadAbstract
TSynBackgroundThreadAbstract
TSynBackgroundThreadProcess
TSynBackgroundTimer
TSynBackgroundThreadMethodAbstract
TSynParallelProcessThread
TSynBackgroundThreadProcedure
TSynBackgroundThreadMethod
TSynBackgroundThreadEventTThread
TSynPersistentStoreTSynQueue
TSynPersistentLockTSynParallelProcess
TSynPersistent
TBlockingProcessPool
TBlockingProcess
TBlockingProcessPoolItem
TSynEventTObject
TSynThreadPool
TPendingTaskList
TInterfacedObjectWithCustomCreate
TLockedDocVariantIInterface
ILockedDocVariant
ESynException
ESynThread

mormot.core.threads class hierarchy

image

1.3. Objects implemented in the mormot.core.threads unit (mormot.core.threads 單元中實現的對象)

Objects Description
ESynThread Exception class raised by this unit 由本單元引發的異常類
ILockedDocVariant Ref-counted interface for thread-safe access to a TDocVariant document 用於線程安全訪問TDocVariant文檔的引用計數介面
TBlockingProcess A semaphore used to wait for some process to be finished 一個計數信號量,用於等待某個進程完成
TBlockingProcessPool Manage a pool of TBlockingProcessPoolItem instances 管理一組TBlockingProcessPoolItem實例
TBlockingProcessPoolItem A semaphore used in the TBlockingProcessPool 在TBlockingProcessPool中使用的計數信號量
TLockedDocVariant Allows thread-safe access to a TDocVariant document 允許線程安全地訪問TDocVariant文檔
TLoggedThread Abstract class to implement a thread with logging notifications 實現帶有日誌通知的線程的抽象類
TLoggedWorkThread A class able to run some process in a background thread 能夠在後臺線程中運行某些進程的類
TNotifiedThread Abstract class to implement a thread with start/stop notifications 實現帶有啟動/停止通知的線程的抽象類
TPendingTaskList Thread-safe list of tasks, stored as RawByteString, with a timestamp 線程安全的任務列表,以RawByteString形式存儲,帶有時間戳
TPendingTaskListItem Internal item definition, used by TPendingTaskList storage TPendingTaskList存儲的內部項目定義
TSynBackgroundThreadAbstract Abstract TThread with its own execution content 帶有自己的執行內容的TThreadAbstract
TSynBackgroundThreadEvent Allow background thread process of a method callback 允許在後臺線程中處理方法回調
TSynBackgroundThreadMethod Allow background thread process of a variable TThreadMethod callback 允許在後臺線程中處理可變TThreadMethod回調
TSynBackgroundThreadMethodAbstract Abstract TThread able to run a method in its own execution content 能夠在自己的執行內容中運行方法的抽象TThread
TSynBackgroundThreadProcedure Allow background thread process of a procedure callback 允許在後臺線程中處理過程回調
TSynBackgroundThreadProcess TThread able to run a method at a given periodic pace 能夠在給定周期速率下運行方法的TThread
TSynBackgroundTimer TThread able to run one or several tasks at a periodic pace in a background thread 能夠在後臺線程中以周期速率運行一個或多個任務的TThread
TSynBackgroundTimerTask Used by TSynBackgroundTimer internal registration list 用於TSynBackgroundTimer內部註冊列表
TSynParallelProcess Allow parallel execution of an index-based process in a thread pool 允許線上程池中並行執行基於索引的進程
TSynParallelProcessThread Thread executing process for TSynParallelProcess 為TSynParallelProcess執行進程的線程
TSynQueue Thread-safe FIFO (First-In-First-Out) in-order queue of records 線程安全的FIFO(先入先出)有序記錄隊列
TSynThread A simple TThread with a "Terminate" event run in the thread context 一個簡單的TThread,帶有線上程上下文中運行的"Terminate"事件
TSynThreadPool A simple Thread Pool, used e.g. for fast handling HTTP/1.0 requests 一個簡單的線程池,例如用於快速處理HTTP/1.0請求
TSynThreadPoolWorkThread Defines the work threads used by TSynThreadPool 定義TSynThreadPool使用的工作線程
TThreadAbstract Abstract parent of all TThread inherited classes 所有TThread繼承類的抽象父類

1.3.1. ESynThread

ESynThread = class(ESynException)

本單元引發的異常類


1.3.2. TSynQueue

TSynQueue = class(TSynPersistentStore)

*線程安全的FIFO(先入先出)記錄有序隊列

  • 內部使用TDynArray存儲,具有滑動演算法,比FPC或Delphi的TQueue或簡單的TDynArray.Add/Delete更高效
  • 如果需要,支持TSynPersistentStore二進位持久化
  • 該結構在設計上也是線程安全的*

constructor Create(aTypeInfo: PRttiInfo; const aName: RawUtf8 = ''); reintroduce; virtual;

*初始化隊列存儲

  • aTypeInfo應是一個動態數組的TypeInfo() RTTI指針,它將在這個TSynQueue實例中存儲值
  • 可以為這個實例可選地分配一個名稱*

destructor Destroy; override;

*銷毀存儲


function Capacity: integer;

*返回當前在記憶體中預留的槽位數

  • 隊列具有優化的自動調整大小演算法,可以使用此方法返回其當前capacity
  • 此方法不是線程安全的,因此返回的值僅具有指示性*

function Count: integer;

*返回當前存儲在此隊列中的項數

  • 此方法不是線程安全的,因此返回的值要麼具有指示性,要麼應使用顯式的安全鎖定/解鎖
  • 如果要檢查隊列是否為空,請調用Pending*

function Peek(out aValue): boolean;

*從隊列中按FIFO(先入先出)方式查找一個項

  • 如果aValue已被填充了一個pending項,而不從隊列中刪除它(如Pop方法所做的),則返回true
  • 如果隊列為空,則返回false
  • 此方法是線程安全的,因為它將鎖定實例*

function Pending: boolean;

*如果隊列中有一些當前pending的項,則返回true

  • 比檢查Count=0更快,並且比PopPeek快得多
  • 此方法不是線程安全的,因此返回的值僅具有指示性*

function Pop(out aValue): boolean;

*從隊列中按FIFO(先入先出)方式提取一個項

  • 如果aValue已被填充了一個pending項,並且該項已從隊列中刪除(如果不想刪除它,請使用Peek),則返回true
  • 如果隊列為空,則返回false
  • 此方法是線程安全的,因為它將鎖定實例*

function PopEquals(aAnother: pointer; aCompare: TDynArraySortCompare; out aValue): boolean;

*從隊列中按FIFO(先入先出)方式提取一個匹配的項

  • 當前pending項與aAnother值進行比較*

function WaitPeekLocked(aTimeoutMS: integer; const aWhenIdle: TThreadMethod): pointer;

*等待從隊列中按FIFO(先入先出)方式查找一個項

  • 在aTimeoutMS時間內返回一個指向pending項的指針
  • 保持Safe.ReadWriteLock,因此調用者可以檢查其內容,然後如果它是預期的項,則調用Pop(),並最終調用Safe.ReadWriteUnlock
  • 如果在時間內沒有將任何內容推入隊列,則返回nil
  • 此方法是線程安全的,但僅在需要時鎖定實例*

function WaitPop(aTimeoutMS: integer; const aWhenIdle: TThreadMethod; out aValue; aCompared: pointer = nil; aCompare: TDynArraySortCompare = nil): boolean;

*等待並從隊列中按FIFO(先入先出)方式提取一個項

  • 如果在指定的aTimeoutMS時間內aValue已被填充了一個pending項,則返回true
  • 如果在時間內沒有將任何內容推入隊列,或者已調用WaitPopFinalize,則返回false
  • aWhenIdle可以被分配,例如給VCL/LCL Application.ProcessMessages
  • 可以在返回之前可選地比較pending項(例如,當多個線程將項放入隊列時可以使用)
  • 此方法是線程安全的,但僅在需要時鎖定實例*

procedure Clear;

*刪除當前存儲在此隊列中的所有項,並清空其capacity

  • 此方法是線程安全的,因為它將鎖定實例*

procedure Push(const aValue);

*將一個項存儲到隊列中

  • 此方法是線程安全的,因為它將鎖定實例*

procedure Save(out aDynArrayValues; aDynArray: PDynArray = nil); overload;

*使用存儲的隊列項初始化一個動態數組

  • aDynArrayValues應是一個在Create中定義的aTypeInfo變數
  • 可以檢索一個可選的TDynArray包裝器,例如用於二進位或JSON持久化
  • 此方法是線程安全的,並將複製隊列數據*

procedure WaitPopFinalize(aTimeoutMS: integer = 100);

*確保任何pending或未來的WaitPop()方法立即返回false

  • 總是由Destroy析構函數調用
  • 也可以從UI的OnClose事件中調用,以避免任何鎖定
  • 此方法是線程安全的,但僅在需要時鎖定實例*

1.3.3. TPendingTaskListItem

TPendingTaskListItem = packed record

內部項目定義,由TPendingTaskList存儲使用


Task: RawByteString;

相關聯的task,以原始二進位形式存儲


Timestamp: Int64;

當TPendingTaskList.GetTimestamp達到此值時,應執行task


1.3.4. TPendingTaskList

TPendingTaskList = class(TObject)

*線程安全的任務列表,以RawByteString形式存儲,並帶有時間戳

  • 你可以向內部列表添加任務,以在給定延遲後執行,使用類似於post/peek的演算法
  • 執行延遲預計不准確,但根據每次NextPendingTask調用和GetTimestamp解析度進行最佳猜測*

constructor Create; reintroduce;

預設返回GetTickCount64來初始化列表記憶體和資源


function NextPendingTask: RawByteString; virtual;

*檢索下一個待處理task

  • 如果當前沒有計劃中的task,則返回''
  • 返回與指定延遲相對應的下一個堆棧*

procedure AddTask(aMilliSecondsDelayFromNow: integer; const aTask: RawByteString); virtual;

從當前時間開始,指定毫秒延遲後Append一個task


procedure AddTasks(const aMilliSecondsDelays: array of integer; const aTasks: array of RawByteString);

*指定任務之間的毫秒延遲後Append多個任務

  • 第一個提供的延遲將從當前時間開始計算,然後它將指定等待下一個提供task需要多長時間——也就是說,aMilliSecondsDelays不是絕對延遲*

procedure Clear; virtual;

清除所有待處理任務


property Count: integer read GetCount;

當前定義了多少個待處理任務


property Task: TPendingTaskListItemDynArray read fTask;

*直接低級訪問內部task列表

  • 警告:此動態數組的長度是列表容量:請使用Count屬性來檢索存儲的確切項數
  • 使用try ... finally Safe.Unlock塊中的Safe.Lock/TryLock進行線程安全訪問此數組
  • 項目按遞增的Timestamp存儲,即第一個項目是NextPendingTask方法將返回的下一個項目*

property Timestamp: Int64 read GetTimestamp;

*訪問內部TPendingTaskListItem.Timestamp存儲的值

  • 對應當前時間
  • 預設實現是返回GetTickCount64,在Windows下典型解析度為16毫秒*

1.3.5. ILockedDocVariant

ILockedDocVariant = interface(IInterface)

*用於線程安全訪問TDocVariant文檔的引用計數介面

  • 例如,由TLockedDocVariant實現,用於IoC/DI解析
  • 快速且安全地存儲任何類似JSON的對象,作為屬性/值對,或類似JSON的數組,作為值*

function AddExistingProp(const Name: RawUtf8; var Obj: variant): boolean;

*將現有屬性value添加到給定的TDocVariant文檔對象

  • 如果Name存在,則返回TRUE並將Name/Value對添加到Obj
  • 如果存儲的文檔中不存在Name,則返回FALSE
  • 此方法在查找Name期間會使用lock,但無論是否返回FALSE,總是會釋放lock(參見AddExistingPropOrLock)*

function AddExistingPropOrLock(const Name: RawUtf8; var Obj: variant): boolean;

*將現有屬性value添加到給定的TDocVariant文檔對象

  • 如果Name存在,則返回TRUE並將Name/Value對添加到Obj,使用內部lock確保線程安全
  • 如果存儲的文檔中不存在Name,則返回FALSE並鎖定內部存儲:調用者最終應通過AddNewPropAndUnlock()釋放lock
  • 可以這樣使用,以實現線程安全的緩存:
if not cache.AddExistingPropOrLock('Articles',Scope) then
  cache.AddNewPropAndUnlock('Articles',GetArticlesFromDB,Scope);

這裡GetArticlesFromDB會在主要lock內部執行


function Copy: variant;

對內部TDocVariant文檔對象或數組進行線程安全的複製


function Exists(const Name: RawUtf8; out Value: Variant): boolean;

*按名稱檢查和返回一個給定的屬性

  • 如果找到Name,則返回TRUE並將與提供的Name相關聯的value填充到Value中,使用內部lock確保線程安全
  • 如果未找到Name,則返回FALSE並釋放內部lock:如果你想要添加缺失的value,請使用ExistsOrLock()*

function ExistsOrLock(const Name: RawUtf8; out Value: Variant): boolean;

*按名稱檢查和返回一個給定的屬性

  • 如果找到Name,則返回TRUE並將與提供的Name相關聯的value填充到Value中,使用內部lock確保線程安全
  • 如果Name不存在,則返回FALSE並設置內部lock:調用者隨後應通過ReplaceAndUnlock()釋放lock*

function Lock: TAutoLocker;

對關聯的線程安全互斥鎖進行低級訪問


function ToJson(HumanReadable: boolean = false): RawUtf8;

將存儲的值保存為UTF-8編碼的JSON對象


procedure AddItem(const Value: variant);

*將value添加到內部TDocVariant文檔數組


procedure AddNewProp(const Name: RawUtf8; const Value: variant; var Obj: variant);

*將屬性value添加到給定的TDocVariant文檔對象

  • 此方法在調用時不會期望資源被鎖定,與AddNewPropAndUnlock不同
  • 將使用內部lock確保線程安全
  • 如果Name已存在,將更新/更改現有的value
  • 可以這樣使用,以實現線程安全的緩存:
if not cache.AddExistingProp('Articles',Scope) then
  cache.AddNewProp('Articles',GetArticlesFromDB,Scope);

這裡GetArticlesFromDB會在主lock之外執行


procedure AddNewPropAndUnlock(const Name: RawUtf8; const Value: variant; var Obj: variant);

*將屬性value添加到給定的TDocVariant文檔對象以及內部存儲的文檔,然後釋放之前的lock

  • 調用此方法之前應由AddExistingPropOrLock()返回false,即在一個已鎖定的實例上執行*

procedure Clear;

刪除所有存儲的屬性


procedure ReplaceAndUnlock(const Name: RawUtf8; const Value: Variant; out LocalValue: Variant);

*通過屬性名稱設置value,並設置本地副本

  • 可以這樣使用,以實現線程安全的緩存:
if not cache.ExistsOrLock('prop',local) then
  cache.ReplaceAndUnlock('prop',newValue,local);
  • 調用此方法之前應由ExistsOrLock()返回false,即在一個已鎖定的實例上執行

property Value[const Name: RawUtf8]: Variant read GetValue write SetValue;

*通過此屬性安全地訪問文檔欄位

  • 這是此存儲的主要入口點
  • 如果在讀取時Name不存在,將引發EDocVariant異常
  • 實現類將對variant value進行線程安全的副本*

1.3.6. TLockedDocVariant

TLockedDocVariant = class(TInterfacedObjectWithCustomCreate)

*允許線程安全地訪問TDocVariant文檔


constructor Create(options: TDocVariantOptions); reintroduce; overload;

使用相應的選項初始化線程安全的文檔存儲


constructor Create(options: TDocVariantModel); reintroduce; overload;

從給定的模板初始化線程安全的文檔存儲


constructor Create; overload; override;

*使用快速的TDocVariant初始化線程安全的文檔


destructor Destroy; override;

銷毀存儲


function AddExistingProp(const Name: RawUtf8; var Obj: variant): boolean;

*向給定的TDocVariant文檔對象添加一個已存在的屬性value

  • 如果Name存在,則返回TRUE並將Name/Value對添加到Obj
  • 如果存儲的文檔中不存在Name,則返回FALSE
  • 此方法在查找Name期間會使用lock,但無論是否返回FALSE,總是會釋放lock(參見AddExistingPropOrLock)*

function AddExistingPropOrLock(const Name: RawUtf8; var Obj: variant): boolean;

*向給定的TDocVariant文檔對象添加一個已存在的屬性value

  • 如果Name存在,則返回TRUE並將Name/Value對添加到Obj
  • 如果存儲的文檔中不存在Name,則返回FALSE,並期望最終調用Lock.Leave或AddNewPropAndUnlock()

function Copy: variant;

對內部TDocVariant文檔對象或數組進行線程安全的複製


function Exists(const Name: RawUtf8; out Value: Variant): boolean;

按名稱檢查和返回一個給定的屬性


function ExistsOrLock(const Name: RawUtf8; out Value: Variant): boolean;

*按名稱檢查和返回一個給定的屬性

  • 如果找到,則返回TRUE並返回現有Name的value
  • 如果未找到,則返回FALSE,並期望最終調用Lock.Leave或ReplaceAndUnlock()

function Lock: TAutoLocker;

對關聯的線程安全互斥鎖進行低級訪問


function ToJson(HumanReadable: boolean = false): RawUtf8;

*將存儲的value保存為UTF-8編碼的JSON對象


procedure AddItem(const Value: variant);

value添加到內部TDocVariant文檔數組


procedure AddNewProp(const Name: RawUtf8; const Value: variant; var Obj: variant);

*向給定的TDocVariant文檔對象添加一個屬性value

  • 此方法在調用時不會期望資源被鎖定,與AddNewPropAndUnlock不同
  • 將使用內部lock確保線程安全
  • 如果Name已存在,將更新/更改現有的value*

procedure AddNewPropAndUnlock(const Name: RawUtf8; const Value: variant; var Obj: variant);

向給定的TDocVariant文檔對象和內部存儲的文檔添加一個屬性value


procedure Clear;

刪除所有存儲的屬性


procedure ReplaceAndUnlock(const Name: RawUtf8; const Value: Variant; out LocalValue: Variant);

通過屬性名稱設置value,並設置本地副本


property Value[const Name: RawUtf8]: variant read GetValue write SetValue;

*將通過此屬性安全地訪問文檔欄位

  • 如果Name不存在,將引發EDocVariant異常
  • 返回的variant結果是副本,不是varByRef,因為副本將更具線程安全性*

1.3.7. TThreadAbstract

TThreadAbstract = class(TThread)

*所有TThread繼承類的抽象父類

  • 利用跨編譯器和跨版本RTL的差異
  • 擁有預期的Start和TerminateSet方法,以及Terminated屬性*

procedure Start;

*調用此方法以start線程

  • Resume在最新的RTL中已被棄用,因為一些操作系統(例如Linux)沒有實現此暫停/恢復功能;我們在此為Delphi的舊版本定義此方法*

procedure Terminate; reintroduce;

重新引入以調用TerminatedSet


procedure TerminatedSet; virtual;

*正確terminate線程


property Terminated;

定義為public,因為可能用於terminate處理方法


1.3.8. TSynBackgroundThreadAbstract

TSynBackgroundThreadAbstract = class(TThreadAbstract)

*具有自身執行內容的抽象TThread


constructor Create(const aThreadName: RawUtf8; const OnBeforeExecute: TOnNotifyThread = nil; const OnAfterExecute: TOnNotifyThread = nil; CreateSuspended: boolean = false); reintroduce;

*初始化線程

  • 可以定義一些回調來嵌套線程執行,例如分配給TRestServer.BeginCurrentThread/EndCurrentThread,或者至少將OnAfterExecute設置為TSynLogFamily.OnThreadEnded*

destructor Destroy; override;

*釋放使用的資源


function SleepOrTerminated(MS: cardinal): boolean;

*Sleep()的安全版本,不會中斷線程進程

  • 如果線程已終止,則返回TRUE
  • 如果成功等待了MS毫秒,則返回FALSE*

procedure TerminatedSet; override;

*正確終止線程

  • 由重新引入的Terminate調用*

procedure WaitForNotExecuting(maxMS: integer = 500);

*等待Execute/ExecuteLoop結束(即fExecute<>exRun)

  • 在迴圈中調用Sleep(),直到達到超時
  • 例如在Destroy中使用,以避免任何GPF並確保乾凈地終結*

property Pause: boolean read fExecuteLoopPause write SetExecuteLoopPause;

*臨時停止ExecuteLoop的執行,直到設置為false


property ProcessEvent: TSynEvent read fProcessEvent;

*訪問與低級別相關的事件,用於通知後臺線程任務執行

  • 可以調用ProcessEvent.SetEvent來觸發內部處理迴圈*


1.3.9. TSynBackgroundThreadMethodAbstract

TSynBackgroundThreadMethodAbstract = class(TSynBackgroundThreadAbstract)

*抽象TThread,能夠在其自己的執行內容中運行方法

  • 典型用途是用於處理數據或遠程訪問的後臺線程,同時UI將保持響應,通過在迴圈中運行OnIdle事件:例如,查看mormot.rest.client.pas單元中TRestClientUri.OnIdle如何處理這種情況
  • 不應直接使用此類,而應從中繼承並重寫Process方法,或使用TSynBackgroundThreadEvent / TSynBackgroundThreadMethod並提供更方便的回調*

constructor Create(const aOnIdle: TOnIdleSynBackgroundThread; const aThreadName: RawUtf8; const OnBeforeExecute: TOnNotifyThread = nil; const OnAfterExecute: TOnNotifyThread = nil); reintroduce;

*初始化線程

  • 如果aOnIdle未設置(即等於nil),它將簡單地等待後臺進程完成,直到RunAndWait()返回
  • 可以定義一些回調來嵌套線程執行,例如分配給TRestServer.BeginCurrentThread/EndCurrentThread*

destructor Destroy; override;

終結線程


function RunAndWait(OpaqueParam: pointer): boolean;

*在後臺線程中非同步啟動Process抽象方法

  • 等待進程完成,同時調用OnIdle()回調
  • 在後臺線程中引發的任何異常都將在調用者線程中轉換
  • 如果self未設置,或者從當前正在處理的同一線程中調用(以避免從OnIdle()回調引發的競態條件),則返回false
  • 當後臺進程完成時返回true
  • OpaqueParam將用於指定後臺進程的線程安全內容
  • 此方法是線程安全的,即它將等待由另一個線程啟動的任何進程:可以從任何線程調用此方法,即使其主要目的是從主UI線程調用*

property OnAfterProcess: TOnNotifyThread read fOnAfterProcess write fOnAfterProcess;

在每個Process之後在Execute中觸發的可選回調事件


property OnBeforeProcess: TOnNotifyThread read fOnBeforeProcess write fOnBeforeProcess;

在每個Process之前在Execute中觸發的可選回調事件


property OnIdle: TOnIdleSynBackgroundThread read fOnIdle write fOnIdle;

*在遠程阻塞進程期間迴圈執行的回調事件,例如,在請求時間較長時刷新UI

  • 可以為此屬性分配一個回調,例如調用Application.ProcessMessages,在後臺線程中執行遠程請求,但讓UI保持響應:mORMotUILogin.pas中的TLoginForm.OnIdleProcess和OnIdleProcessForm方法將滿足此屬性的預期
  • 如果OnIdle未設置(即等於nil),它將簡單地等待後臺進程完成,直到RunAndWait()返回*

property OnIdleBackgroundThreadActive: boolean read GetOnIdleBackgroundThreadActive;

*如果後臺線程處於活動狀態,並且在處理過程中調用了OnIdle事件,則為TRUE

  • 例如,用於確保用戶界面消息不會重新進入*

1.3.10. TSynBackgroundThreadEvent

TSynBackgroundThreadEvent = class(TSynBackgroundThreadMethodAbstract)

允許後臺線程處理方法回調


constructor Create(const aOnProcess: TOnProcessSynBackgroundThread; const aOnIdle: TOnIdleSynBackgroundThread; const aThreadName: RawUtf8); reintroduce;

*初始化線程

  • 如果aOnIdle未設置(即等於nil),它將簡單地等待後臺進程完成,直到RunAndWait()返回*

property OnProcess: TOnProcessSynBackgroundThread read fOnProcess write fOnProcess;

*提供一個在後臺線程中執行的方法處理程式

  • 由RunAndWait()方法觸發 - 該方法將等待直到完成
  • 在RunAndWait()中指定的OpaqueParam將在此處提供*

1.3.11. TSynBackgroundThreadMethod

TSynBackgroundThreadMethod = class(TSynBackgroundThreadMethodAbstract)

允許後臺線程處理可變的TThreadMethod回調


procedure RunAndWait(Method: TThreadMethod); reintroduce;

*運行一次提供的TThreadMethod回調

  • 使用此方法,而不是繼承的RunAndWait()*

1.3.12. TSynBackgroundThreadProcedure

TSynBackgroundThreadProcedure = class(TSynBackgroundThreadMethodAbstract)

允許後臺線程處理過程回調


constructor Create(aOnProcess: TOnProcessSynBackgroundThreadProc; const aOnIdle: TOnIdleSynBackgroundThread; const aThreadName: RawUtf8); reintroduce;

*初始化線程

  • 如果aOnIdle未設置(即等於nil),它將簡單地等待後臺進程完成,直到RunAndWait()返回*

property OnProcess: TOnProcessSynBackgroundThreadProc read fOnProcess write fOnProcess;

*提供一個在後臺線程中執行的過程處理程式

  • 由RunAndWait()方法觸發 - 該方法將等待直到完成
  • 在RunAndWait()中指定的OpaqueParam將在此處提供*

1.3.13. TSynBackgroundThreadProcess

TSynBackgroundThreadProcess = class(TSynBackgroundThreadAbstract)

能夠在給定周期速率下運行方法的TThread


constructor Create(const aThreadName: RawUtf8; const aOnProcess: TOnSynBackgroundThreadProcess; aOnProcessMS: cardinal; const aOnBeforeExecute: TOnNotifyThread = nil; const aOnAfterExecute: TOnNotifyThread = nil; aStats: TSynMonitorClass = nil; CreateSuspended: boolean = false); reintroduce; virtual;

*初始化線程以進行周期性任務處理

  • 當調用ProcessEvent.SetEvent或自上次處理以來已經過去了aOnProcessMS毫秒周期時,將調用aOnProcess
  • 如果aOnProcessMS為0,將等待直到調用ProcessEvent.SetEvent
  • 可以定義一些回調來嵌套線程執行,例如分配給TRestServer.BeginCurrentThread/EndCurrentThread*

destructor Destroy; override;

終結線程並等待其結束


property OnException: TNotifyEvent read fOnException write fOnException;

*當OnProcess引發異常時執行的事件回調

  • 提供的Sender參數是引發的異常實例*

property OnProcess: TOnSynBackgroundThreadProcess read fOnProcess;

訪問周期性任務的實現事件


property OnProcessMS: cardinal read fOnProcessMS write fOnProcessMS;

訪問周期性任務處理的延遲(以毫秒為單位)


property Stats: TSynMonitor read fStats;

*處理統計信息

  • 如果在類構造函數中aStats為nil,則可能為nil*

1.3.14. TSynBackgroundTimerTask

TSynBackgroundTimerTask = record

TSynBackgroundTimer內部註冊列表使用


1.3.15. TSynBackgroundTimer

TSynBackgroundTimer = class(TSynBackgroundThreadProcess)

*能夠在後臺線程中以周期速率運行一個或多個任務的TThread

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這篇文章介紹瞭如何在TypeScript環境下為Vue.js應用搭建項目結構,包括初始化配置、創建Vue組件、實現狀態管理利用Vuex、配置路由以及性能優化的方法,旨在提升開發效率與應用性能。 ...
  • 這篇文章介紹瞭如何使用Vue CLI優化項目構建配置,提高開發效率,涉及配置管理、項目部署策略、插件系統定製以及Webpack和TypeScript的深度集成技巧。 ...
  • 這篇文章介紹瞭如何在Vue框架中實現數據的高效驗證與處理,以及如何集成ECharts、D3.js、Chart.js等圖表庫優化數據可視化效果。同時,探討了Progressive Web App(PWA)的接入與優化策略,以提升Web應用的用戶體驗與載入速度。 ...
  • JavaScript 引擎的工作方式是,先解析代碼,獲取所有被聲明的變數,然後再一行一行地運行。這造成的結果,就是所有變數的聲明語句,都會被提升到代碼的頭部,這就叫做變數提升(hoisting)。 console.log(a); // undefined var a = 1; 上面的代碼首先使用 c ...
  • 這篇文章介紹瞭如何在Vue.js應用中利用Vue Router實現單頁面應用的路由管理,包括配置路由、導航守衛的使用、路由懶載入以優化性能以及動態路由的實現方法,旨在提升用戶體驗和應用載入效率 ...
  • Popover API 為開發者提供了一種聲明式的方式來創建各種類型的彈窗。目前已在所有三大瀏覽器引擎中可用,並正式成為 Baseline 2024 的一部分。 ...
  • 前言 眾所周知,vue3的template中使用ref變數無需使用.value。還可以在事件處理器中進行賦值操作時,無需使用.value就可以直接修改ref變數的值,比如:<button @click="msg = 'Hello Vue3'">change msg</button>。你猜vue是在編 ...
  • 政務雲參考技術架構行業優勢總體架構 政務雲平臺技術框架圖,由機房環境、基礎設施層、支撐軟體層及業務應用層組成,在運維、安全和運營體系的保障下,為政務雲使用單位提供統一服務支撐。功能架構標準雙區隔離 參照國家電子政務規範,打造符合標準的雙區隔離的政務雲平臺,互聯網區承載對公服務業務,政務外網區承載各單 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...