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 | Motivo terminal estruturado que cobre solicitações do usuário, tempos limite expirados, trabalho vinculado, desligamento, trabalho superado e cancelamento definido pelo aplicativo |
EPdfOperationCancelled | Exceção de cancelamento com o Reason e a mensagem originais preservados para diagnósticos |
IPdfCancellationToken | Token de compatibilidade do lado do worker com polling de IsCancelled, RegisterCallback, ThrowIfCancelled e suporte a exceções |
IPdfCancellationTokenSource | Fonte de compatibilidade do lado do proprietário com Token e Cancel idempotente |
IPdfCancellationRegistration | Registro de callback estável com Id, IsRegistered e Unregister thread-safe |
IPdfCancellationTokenEx | Token estendido com metadados de cancelamento, contagens de callbacks, registro de callback removível e espera baseada em eventos |
IPdfCancellationTokenSourceEx | Fonte estendida do proprietário com TryCancel atômico, CancelWithReason e TokenEx fortemente tipado |
TPdfCancellationTokenSource | Implementação thread-safe da fonte criada com New, NewEx ou NewTimeout |
PdfNoCancellationToken | Token compartilhado que nunca é cancelado e evita alocar uma fonte para trabalho não cancelável |
| Type | Description |
|---|---|
TPdfFutureStatus | Estado do resultado: pfsSuccess, pfsCancelled ou pfsFailure |
TPdfFutureDispatchMode | Política de resposta: pfdSynchronize envia a resposta para a thread principal, pfdWorkerThread a invoca na worker e pfdNone suprime a resposta |
TPdfFutureOptions | Configurações de RunEx para despacho da resposta e ThreadPriority da worker |
TPdfFutureResult<T> | Envolvente de conclusão com Value e HasValue, Status, o par ErrorMessage e ErrorClassName, o CancellationReason, OperationId, StartedAtTick e CompletedAtTick, auxiliares de status e ElapsedMilliseconds |
TPdfFutureWorker<T> | Worker de ponteiro de método que recebe um token de cancelamento e retorna o resultado em segundo plano |
TPdfFutureReply<T> | Callback de ponteiro de método que recebe o TPdfFutureResult<T> concluído |
TPdfFutureThread<T> | Tipo de thread de suporte ao compilador usado por TPdfFuture<T>; construído por meio de Create ou do CreateEx que considera opções, e os aplicativos normalmente chamam Run ou RunEx |
TPdfFuture<T> | Auxiliar fire-and-forget que preserva o comportamento original de resposta sincronizada por meio de Run e adiciona despacho configurável por meio de RunEx |
| Type | Description |
|---|---|
TPdfAsyncPriority | Quatro filas de desenfileiramento de papLow a papCritical, com ordem FIFO dentro de cada fila |
TPdfAsyncTaskState | Ciclo de vida da tarefa: patsQueued, patsRunning, patsSucceeded, patsCancelled ou patsFailed |
TPdfAsyncDispatchMode | Despacho da resposta por meio de padWorkerThread, padSynchronize ou padNone para suprimir a resposta |
TPdfAsyncTaskWorker | Item de trabalho de ponteiro de método que recebe o token de cancelamento de sua tarefa |
TPdfAsyncTaskReply | Callback de conclusão de ponteiro de método que recebe um snapshot imutável do resultado da tarefa |
TPdfAsyncTaskResult | Cronometragem de TaskId, State, Priority, QueuedAtTick, StartedAtTick e CompletedAtTick, o par de erros do worker ErrorMessage e ErrorClassName, o CancellationReason com sua mensagem e o ReplyErrorMessage isolado |
IPdfAsyncTask | Handle da tarefa enviada com Cancel, WaitFor ciente de tempo limite, Snapshot atômico e as propriedades Id, State, Priority, Token e IsCompleted |
TPdfAsyncExecutorStats | Capacidade, carga atual, profundidade de pico da fila e contagens cumulativas de envios, sucessos, cancelamentos, falhas e rejeições |
EPdfAsyncQueueFull | Disparada por Submit quando uma fila limitada não pode aceitar outra tarefa |
EPdfAsyncExecutorShutdown | Disparada por Submit depois que o desligamento do executor começa |
TPdfAsyncExecutor | Pool de workers fixo e reutilizável com fila limitada, quatro anéis de prioridade O(1), cancelamento cooperativo de tarefas, estatísticas e desligamento gracioso |
| Function | Description |
|---|---|
PdfAsyncTick | Retorna o tick monotônico em milissegundos usado pelos metadados de futures e do executor |
PdfAsyncTickDelta | Calcula um valor defensivo de milissegundos decorridos e retorna zero para ticks ausentes ou invertidos |
PdfNextAsyncId | Retorna um ID positivo local do processo compartilhado por futures, registros de callbacks e tarefas do executor |
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;
Compilações Delphi POSIX mantêm os valores de opção TThreadPriority tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest e tpTimeCritical por compatibilidade de código-fonte, mas a RTL da plataforma suporta apenas o caminho de agendamento padrão. tpNormal usa esse caminho; construir um future com outra prioridade de thread dispara ENotSupportedException antes de iniciar um worker
Use TPdfAsyncExecutor para trabalho repetido ou em rajadas, de modo que as tarefas reutilizem um conjunto fixo de threads em vez de criar uma thread por operação
Uma capacidade de fila positiva fornece backpressure determinístico, enquanto zero mantém a fila ilimitada; tarefas em execução não consomem vagas da fila
O agendamento por prioridade é estrito entre filas e FIFO dentro de uma fila, portanto reserve papCritical e papHigh para trabalho genuinamente sensível à latência
WaitForIdle processa callbacks sincronizados quando chamado da thread principal, permitindo que respostas padSynchronize terminem sem deadlock no desligamento
Cada fonte de tempo limite possui uma thread de espera leve até o cancelamento ou a expiração, de modo que um temporizador de aplicativo compartilhado ou um agendador de prazos é preferível ao criar números muito grandes de prazos curtos e de vida breve
As regras de posse de objetos do PDFium continuam valendo: crie ou isole uma instância de TPdf por worker concorrente e não mute nem renderize simultaneamente a mesma instância de documento ativo
As APIs originais IPdfCancellationToken, IPdfCancellationTokenSource, TPdfCancellationTokenSource.New e TPdfFuture<T>.Run permanecem compatíveis em nível de código-fonte
Use as interfaces estendidas somente quando forem exigidos diagnósticos estruturados, callbacks removíveis, espera com tempo limite ou posse atômica do cancelamento
Os callbacks permanecem ponteiros de método em vez de anonymous methods, de forma que a mesma API compila com Delphi, C++Builder e Free Pascal