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 | Strukturerad slutorsak som täcker användarönskningar, timeout, länkat arbete, avstängning, ersatt arbete och applikationsdefinierad avbrytning |
EPdfOperationCancelled | Avbrottsundantag med den ursprungliga Reason och meddelandet bevarat för diagnostik |
IPdfCancellationToken | Kompatibilitetstoken för arbetarsidan med IsCancelled-pollning, RegisterCallback, ThrowIfCancelled och undantagsstöd |
IPdfCancellationTokenSource | Kompatibilitetskälla för ägarsidans med Token och idempotent Cancel |
IPdfCancellationRegistration | Stabil callback-registrering med Id, IsRegistered och trådsäker Unregister |
IPdfCancellationTokenEx | Utökad token med avbrottsmetadata, callback-räknare, avlägsnbar callback-registrering och händelsebaserad väntan |
IPdfCancellationTokenSourceEx | Utökad ägarkälla med atomär TryCancel, CancelWithReason och starkt typad TokenEx |
TPdfCancellationTokenSource | Trådsäker källimplementering som skapas med New, NewEx eller NewTimeout |
PdfNoCancellationToken | Delad token som aldrig avbryter och slipper allokera en källa för arbete som inte kan avbrytas |
| Type | Description |
|---|---|
TPdfFutureStatus | Resultattillstånd: pfsSuccess, pfsCancelled eller pfsFailure |
TPdfFutureDispatchMode | Svarspolicy: pfdSynchronize postar svaret till huvudtråden, pfdWorkerThread anropar det på arbetartråden och pfdNone undertrycker svaret |
TPdfFutureOptions | RunEx-inställningar för svarssändning och arbetarens ThreadPriority |
TPdfFutureResult<T> | Klarmäkovering med Value och HasValue, Status, paret ErrorMessage och ErrorClassName, CancellationReason, OperationId, StartedAtTick och CompletedAtTick, statushjälpare samt ElapsedMilliseconds |
TPdfFutureWorker<T> | Metodpekararbetare som tar emot en avbrytningstoken och returnerar bakgrundsresultatet |
TPdfFutureReply<T> | Metod pekarcallback som tar emot det färdiga TPdfFutureResult<T> |
TPdfFutureThread<T> | Trådtyp för kompilatorstöd som TPdfFuture<T> använder; konstruerad via Create eller den inställningskänsliga CreateEx, och applikationer anropar normalt Run eller RunEx |
TPdfFuture<T> | Fire-and-forget-hjälpare som bevarar det ursprungliga synkroniserade svarsbeteendet via Run och lägger till konfigurerbar sändning via RunEx |
| Type | Description |
|---|---|
TPdfAsyncPriority | Fyra köbanor från papLow till papCritical, med FIFO-ordning inom varje bana |
TPdfAsyncTaskState | Uppgiftslivscykel: patsQueued, patsRunning, patsSucceeded, patsCancelled eller patsFailed |
TPdfAsyncDispatchMode | Svarssändning via padWorkerThread, padSynchronize eller padNone för att undertrycka svaret |
TPdfAsyncTaskWorker | Metodpekararbetsobjekt som tar emot sitt uppgiftsavbrytningstoken |
TPdfAsyncTaskReply | Metodpekarcallback för klarmäkning som tar emot en oföränderlig ögonblicksbild av uppgiftsresultatet |
TPdfAsyncTaskResult | TaskId, State, Priority, tidsmätning i QueuedAtTick, StartedAtTick och CompletedAtTick, paret ErrorMessage och ErrorClassName för arbetarfel, CancellationReason med sitt meddelande samt det isolerade ReplyErrorMessage |
IPdfAsyncTask | Handtag till en skickad uppgift med Cancel, timeoutkänslig WaitFor, atomär Snapshot och egenskaperna Id, State, Priority, Token och IsCompleted |
TPdfAsyncExecutorStats | Kapacitet, aktuell beläggning, högsta ködjup och kumulativa räknare för skickade, lyckade, avbrutna, misslyckade och avvisade uppgifter |
EPdfAsyncQueueFull | Kastas av Submit när en avgränsad kö inte kan ta emot ytterligare en uppgift |
EPdfAsyncExecutorShutdown | Kastas av Submit efter att exekutorns avstängning har påbörjats |
TPdfAsyncExecutor | Återanvändbar fast arbetspool med avgränsad kö, fyra O(1)-prioritetsringar, kooperativ uppgiftsavbrytning, statistik och kontrollerad avstängning |
| Function | Description |
|---|---|
PdfAsyncTick | Returnerar den monotona millisekundtickan som future- och exekutormetadata använder |
PdfAsyncTickDelta | Beräknar ett skyddat förflutet millisekundvärde och returnerar noll för saknade eller omvända tickor |
PdfNextAsyncId | Returnerar ett processlokalt positivt ID som delas av futures, callback-registreringar och exekutoruppgifter |
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;
Delphi-byggen för POSIX behåller alternativvärdena för TThreadPriority — tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest och tpTimeCritical — för källkompatibilitet, men plattformens RTL stöder bara standardvägen för schemaläggning. tpNormal använder den vägen; att skapa en future med någon annan trådprioritet utlöser ENotSupportedException innan någon worker startas
Använd TPdfAsyncExecutor för upprepat eller utbudsartat arbete så att uppgifter återanvänder en fast uppsättning trådar i stället för att skapa en tråd per operation
En positiv kökapacitet ger deterministisk backpressure medan noll lämnar kön obegränsad; pågående uppgifter förbrukar inga köplatser
Prioritetsschemaläggningen är strikt mellan banor och FIFO inom en bana, så reservera papCritical och papHigh för arbete som verkligen är latenskänsligt
WaitForIdle behandlar synkroniserade callbacks när den anropas från huvudtråden, vilket gör att padSynchronize-svar kan avslutas utan att avstängningen låser sig
Varje timeoutkälla äger en lättviktig väntetråd tills avbrott eller utgång, så en delad applikationstimer eller deadline-schemaläggare är att föredra när mycket stora mängder kortlivade deadlines skapas
PDFiums ägarskapsregler för objekt gäller fortfarande: skapa eller isolera en TPdf-instans per samtidig arbetare och mutera eller rendera inte samma aktiva dokumentinstans samtidigt
De ursprungliga API:erna IPdfCancellationToken, IPdfCancellationTokenSource, TPdfCancellationTokenSource.New och TPdfFuture<T>.Run förblir källkompatibla
Använd de utökade gränssnitten bara när strukturerad diagnostik, avlägsnbara callbacks, timeoutväntan eller atomärt avbrottsägarskap krävs
Callbacks förblir metodpekare i stället för anonyma metoder så att samma API kompilerar med Delphi, C++Builder och Free Pascal