TPdfCancellationReason = (pcrNone, pcrUser, pcrTimeout, pcrLinked,
pcrShutdown, pcrSuperseded, pcrOther);
IPdfCancellationTokenEx = interface(IPdfCancellationToken)
function RegisterCallbackManaged(const ACallback: TThreadMethod): IPdfCancellationRegistration;
function WaitForCancellation(ATimeoutMs: Cardinal): Boolean;
property Reason: TPdfCancellationReason read GetReason;
property CancellationMessage: string read GetCancellationMessage;
property CancelledAtTick: UInt64 read GetCancelledAtTick;
property CallbackCount: Integer read GetCallbackCount;
property HasCallbacks: Boolean read GetHasCallbacks;
end;
IPdfCancellationTokenSourceEx = interface(IPdfCancellationTokenSource)
function TryCancel: Boolean;
function CancelWithReason(AReason: TPdfCancellationReason; const AMessage: string): Boolean;
property TokenEx: IPdfCancellationTokenEx read GetTokenEx;
end;
TPdfCancellationTokenSource = class
destructor Destroy; override;
class function New: IPdfCancellationTokenSource; static;
class function NewEx: IPdfCancellationTokenSourceEx; static;
class function NewTimeout(AMilliseconds: Cardinal; const AMessage: string = ''): IPdfCancellationTokenSourceEx; static;
end;
TPdfFutureOptions = record
DispatchMode: TPdfFutureDispatchMode;
ThreadPriority: TThreadPriority;
class function Default: TPdfFutureOptions; static;
end;
TPdfFuture<T> = class
class procedure Run(const AWorker: TPdfFutureWorker<T>; const AReply: TPdfFutureReply<T>; const AToken: IPdfCancellationToken = nil); static;
class procedure RunEx(const AWorker: TPdfFutureWorker<T>; const AReply: TPdfFutureReply<T>; const AToken: IPdfCancellationToken; const AOptions: TPdfFutureOptions); static;
end;
TPdfAsyncExecutor = class
constructor Create(AWorkerCount: Integer; AQueueCapacity: Integer = 0);
destructor Destroy; override;
function Submit(const AWorker: TPdfAsyncTaskWorker; const AReply: TPdfAsyncTaskReply = nil; APriority: TPdfAsyncPriority = papNormal; ADispatchMode: TPdfAsyncDispatchMode = padWorkerThread): IPdfAsyncTask;
function TrySubmit(const AWorker: TPdfAsyncTaskWorker; const AReply: TPdfAsyncTaskReply; out ATask: IPdfAsyncTask; APriority: TPdfAsyncPriority = papNormal; ADispatchMode: TPdfAsyncDispatchMode = padWorkerThread): Boolean;
function WaitForIdle(ATimeoutMs: Cardinal): Boolean;
function GetStats: TPdfAsyncExecutorStats;
procedure Shutdown(ACancelPending: Boolean = True);
property WorkerCount: Integer read FWorkerCount;
property QueueCapacity: Integer read FQueueCapacity;
property IsShutdown: Boolean read GetIsShutdown;
end;
TPdfAsyncExecutorStats = record
WorkerCount: Integer;
QueueCapacity: Integer;
QueuedCount: Integer;
RunningCount: Integer;
PeakQueuedCount: Integer;
SubmittedCount: Int64;
SucceededCount: Int64;
CancelledCount: Int64;
FailedCount: Int64;
RejectedCount: Int64;
end;
IPdfAsyncTask = interface
function Cancel: Boolean;
function WaitFor(ATimeoutMs: Cardinal): Boolean;
function Snapshot: TPdfAsyncTaskResult;
property Id: Int64 read GetId;
property State: TPdfAsyncTaskState read GetState;
property Priority: TPdfAsyncPriority read GetPriority;
property Token: IPdfCancellationToken read GetToken;
property IsCompleted: Boolean read GetIsCompleted;
end;
| Type | Description |
|---|---|
TPdfCancellationReason | Raison terminale structurée couvrant les demandes utilisateur, les délais d’attente, les travaux liés, l’arrêt, les travaux remplacés et l’annulation définie par l’application |
EPdfOperationCancelled | Exception d’annulation dont la Reason et le message d’origine sont conservés pour le diagnostic |
IPdfCancellationToken | Jeton côté worker de compatibilité avec sondage IsCancelled, RegisterCallback, ThrowIfCancelled et prise en charge des exceptions |
IPdfCancellationTokenSource | Source côté propriétaire de compatibilité avec Token et Cancel idempotent |
IPdfCancellationRegistration | Enregistrement de rappel stable avec Id, IsRegistered et Unregister thread-safe |
IPdfCancellationTokenEx | Jeton étendu avec métadonnées d’annulation, comptages de rappels, enregistrement de rappels amovible et attente adossée à des événements |
IPdfCancellationTokenSourceEx | Source propriétaire étendue avec TryCancel atomique, CancelWithReason et TokenEx fortement typé |
TPdfCancellationTokenSource | Implémentation de source thread-safe créée avec New, NewEx ou NewTimeout |
PdfNoCancellationToken | Jeton partagé qui ne s’annule jamais et évite d’allouer une source pour les travaux non annulables |
| Type | Description |
|---|---|
TPdfFutureStatus | État du résultat : pfsSuccess, pfsCancelled ou pfsFailure |
TPdfFutureDispatchMode | Politique de réponse : pfdSynchronize publie la réponse sur le thread principal, pfdWorkerThread l’invoque sur le worker et pfdNone supprime la réponse |
TPdfFutureOptions | Réglages de RunEx pour la distribution des réponses et la ThreadPriority du worker |
TPdfFutureResult<T> | Enveloppe d’achèvement avec Value et HasValue, Status, la paire ErrorMessage et ErrorClassName, la CancellationReason, OperationId, StartedAtTick et CompletedAtTick, les assistants d’état et ElapsedMilliseconds |
TPdfFutureWorker<T> | Worker à pointeur de méthode qui reçoit un jeton d’annulation et renvoie le résultat d’arrière-plan |
TPdfFutureReply<T> | Rappel à pointeur de méthode qui reçoit la TPdfFutureResult<T> achevée |
TPdfFutureThread<T> | Type de thread de support compilateur utilisé par TPdfFuture<T> ; construit via Create ou CreateEx tenant compte des options, et les applications appellent normalement Run ou RunEx |
TPdfFuture<T> | Assistant fire-and-forget qui conserve le comportement d’origine de réponse synchronisée via Run et ajoute une distribution configurable via RunEx |
| Type | Description |
|---|---|
TPdfAsyncPriority | Quatre files de retrait de papLow à papCritical, avec un ordre FIFO à l’intérieur de chaque file |
TPdfAsyncTaskState | Cycle de vie de tâche : patsQueued, patsRunning, patsSucceeded, patsCancelled ou patsFailed |
TPdfAsyncDispatchMode | Distribution des réponses via padWorkerThread, padSynchronize ou padNone pour supprimer la réponse |
TPdfAsyncTaskWorker | Élément de travail à pointeur de méthode qui reçoit son jeton d’annulation de tâche |
TPdfAsyncTaskReply | Rappel d’achèvement à pointeur de méthode recevant un instantané immuable du résultat de tâche |
TPdfAsyncTaskResult | TaskId, State, Priority, chronométrage QueuedAtTick, StartedAtTick et CompletedAtTick, paire d’erreurs worker ErrorMessage et ErrorClassName, CancellationReason avec son message et ReplyErrorMessage isolé |
IPdfAsyncTask | Handle de tâche soumise avec Cancel, WaitFor tenant compte du délai d’attente, Snapshot atomique et les propriétés Id, State, Priority, Token et IsCompleted |
TPdfAsyncExecutorStats | Capacité, charge courante, profondeur de file crête et comptages cumulés de soumissions, succès, annulations, échecs et rejets |
EPdfAsyncQueueFull | Levée par Submit lorsqu’une file bornée ne peut accepter une autre tâche |
EPdfAsyncExecutorShutdown | Levée par Submit après le démarrage de l’arrêt de l’exécuteur |
TPdfAsyncExecutor | Pool de workers fixe réutilisable avec file bornée, quatre anneaux de priorité O(1), annulation coopérative des tâches, statistiques et arrêt normal |
| Fonction | Description |
|---|---|
PdfAsyncTick | Renvoie le tick monotone en millisecondes utilisé par les métadonnées des futures et de l’exécuteur |
PdfAsyncTickDelta | Calcule une valeur défensive de millisecondes écoulées et renvoie zéro pour des ticks absents ou inversés |
PdfNextAsyncId | Renvoie un ID positif local au processus partagé par les futures, les enregistrements de rappels et les tâches de l’exécuteur |
var
CancelSource: IPdfCancellationTokenSourceEx;
begin
CancelSource := TPdfCancellationTokenSource.NewTimeout(5000, 'Export deadline exceeded');
TPdfFuture<Integer>.Run(Worker, Completed, CancelSource.TokenEx);
if UserRequestedCancel then
CancelSource.CancelWithReason(pcrUser, 'Export cancelled by user');
end;
var
Executor: TPdfAsyncExecutor;
Task: IPdfAsyncTask;
begin
Executor := TPdfAsyncExecutor.Create(4, 128);
try
if not Executor.TrySubmit(RenderPage, PageCompleted, Task, papHigh, padSynchronize) then
HandleBackpressure;
Executor.WaitForIdle(30000);
finally
Executor.Free;
end;
end;
Les builds Delphi POSIX conservent les valeurs TThreadPriority tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest et tpTimeCritical pour la compatibilité source, mais la RTL plateforme ne prend en charge que l’ordonnancement par défaut ; tpNormal l’utilise ; construire un future avec une autre priorité lève ENotSupportedException avant de démarrer un worker
Utilisez TPdfAsyncExecutor pour les travaux répétitifs ou en rafale afin que les tâches réutilisent un ensemble fixe de threads au lieu de créer un thread par opération
Une capacité de file positive fournit une contre-pression déterminée tandis que zéro laisse la file non bornée ; les tâches en cours ne consomment pas d’emplacements de file
L’ordonnancement par priorité est strict entre les files et FIFO au sein d’une file, réservez donc papCritical et papHigh aux travaux réellement sensibles à la latence
WaitForIdle traite les rappels synchronisés lorsqu’il est appelé depuis le thread principal, permettant aux réponses padSynchronize de se terminer sans blocage lors de l’arrêt
Chaque source de délai d’attente possède un thread d’attente léger jusqu’à l’annulation ou l’expiration, de sorte qu’un minuteur d’application partagé ou un ordonnanceur d’échéances est préférable lors de la création d’un très grand nombre d’échéances de courte durée
Les règles de propriété des objets PDFium s’appliquent toujours : créez ou isolez une instance TPdf par worker concurrent et ne modifiez pas et n’effectuez pas le rendu de la même instance de document active de manière simultanée
Les API d’origine IPdfCancellationToken, IPdfCancellationTokenSource, TPdfCancellationTokenSource.New et TPdfFuture<T>.Run restent compatibles au niveau des sources
Utilisez les interfaces étendues uniquement lorsqu’un diagnostic structuré, des rappels amovibles, une attente avec délai ou une propriété d’annulation atomique sont requis
Les rappels restent des pointeurs de méthode plutôt que des méthodes anonymes afin que la même API compile avec Delphi, C++Builder et Free Pascal