PDFium Delphi Component Docs

Unité FPdfAsync

Unité : FPdfAsync
Infrastructure d’annulation, de futures et de pool de workers borné pour un traitement PDF réactif dans les applications VCL, LCL, FMX et headless

Syntaxe

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;

Types d’annulation

TypeDescription
TPdfCancellationReasonRaison 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
EPdfOperationCancelledException d’annulation dont la Reason et le message d’origine sont conservés pour le diagnostic
IPdfCancellationTokenJeton côté worker de compatibilité avec sondage IsCancelled, RegisterCallback, ThrowIfCancelled et prise en charge des exceptions
IPdfCancellationTokenSourceSource côté propriétaire de compatibilité avec Token et Cancel idempotent
IPdfCancellationRegistrationEnregistrement de rappel stable avec Id, IsRegistered et Unregister thread-safe
IPdfCancellationTokenExJeton étendu avec métadonnées d’annulation, comptages de rappels, enregistrement de rappels amovible et attente adossée à des événements
IPdfCancellationTokenSourceExSource propriétaire étendue avec TryCancel atomique, CancelWithReason et TokenEx fortement typé
TPdfCancellationTokenSourceImplémentation de source thread-safe créée avec New, NewEx ou NewTimeout
PdfNoCancellationTokenJeton partagé qui ne s’annule jamais et évite d’allouer une source pour les travaux non annulables

Types de futures

TypeDescription
TPdfFutureStatusÉtat du résultat : pfsSuccess, pfsCancelled ou pfsFailure
TPdfFutureDispatchModePolitique de réponse : pfdSynchronize publie la réponse sur le thread principal, pfdWorkerThread l’invoque sur le worker et pfdNone supprime la réponse
TPdfFutureOptionsRé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

Types d’exécuteurs

TypeDescription
TPdfAsyncPriorityQuatre files de retrait de papLow à papCritical, avec un ordre FIFO à l’intérieur de chaque file
TPdfAsyncTaskStateCycle de vie de tâche : patsQueued, patsRunning, patsSucceeded, patsCancelled ou patsFailed
TPdfAsyncDispatchModeDistribution 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
TPdfAsyncTaskReplyRappel d’achèvement à pointeur de méthode recevant un instantané immuable du résultat de tâche
TPdfAsyncTaskResultTaskId, State, Priority, chronométrage QueuedAtTick, StartedAtTick et CompletedAtTick, paire d’erreurs worker ErrorMessage et ErrorClassName, CancellationReason avec son message et ReplyErrorMessage isolé
IPdfAsyncTaskHandle 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
TPdfAsyncExecutorStatsCapacité, charge courante, profondeur de file crête et comptages cumulés de soumissions, succès, annulations, échecs et rejets
EPdfAsyncQueueFullLevée par Submit lorsqu’une file bornée ne peut accepter une autre tâche
EPdfAsyncExecutorShutdownLevée par Submit après le démarrage de l’arrêt de l’exécuteur
TPdfAsyncExecutorPool 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

Fonctions d’aide pour le temps et l’identification

FonctionDescription
PdfAsyncTickRenvoie le tick monotone en millisecondes utilisé par les métadonnées des futures et de l’exécuteur
PdfAsyncTickDeltaCalcule une valeur défensive de millisecondes écoulées et renvoie zéro pour des ticks absents ou inversés
PdfNextAsyncIdRenvoie un ID positif local au processus partagé par les futures, les enregistrements de rappels et les tâches de l’exécuteur

Exemple d’annulation

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;

Exemple d’exécuteur à capacité limitée

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;

Performances et gestion des threads

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

Compatibilité

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

Voir aussi

TPdf.RenderPageProgressive, TPdfView.AsyncRendering