IProtocolActor Interface¶
A protocol instance's documented threading model (arc42 §8.3, ADR-6; FR-RAW-020..024): exactly one mailbox, processed by exactly one logical loop, so a protocol instance's internal state (channel registers, timer queues, state machines) is never mutated from more than one place at a time — no locks needed by the protocol code itself (FR-RAW-020/021). Scheduling is event-driven, never a busy loop (FR-RAW-022); background exceptions are surfaced via BackgroundExceptionOccurred instead of being thrown on some unrelated caller thread or lost as an unobserved task exception (FR-RAW-023).
Derived
↳ ProtocolActor
Implements IDisposable
Methods¶
IProtocolActor.Post(Action) Method¶
Enqueues work to run on the actor's mailbox loop and returns immediately ("tell" / fire-and-forget). If work throws, the exception is caught by the loop and surfaced via BackgroundExceptionOccurred — there is no other way for a fire-and-forget caller to observe it (FR-RAW-023).
Parameters¶
work Action
IProtocolActor.PostAsync(Action, CancellationToken) Method¶
Enqueues work to run on the actor's mailbox loop and returns a task that completes once it has run ("ask"). Unlike Post(Action), an exception from work is surfaced through the returned task's fault, not through BackgroundExceptionOccurred — the caller is already positioned to observe it by awaiting.
cancellationToken withdraws work for as long as it has not started: a token cancelled before the call, or while the item waits in the mailbox, cancels the returned task at once and the work never runs. Work that has already started is never interrupted — it runs to completion, and cancelling then has no effect on the task's outcome, so the mailbox's single-writer discipline (FR-RAW-021) is not weakened by a half-finished work item.
System.Threading.Tasks.Task PostAsync(System.Action work, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
Parameters¶
work Action
The work to run on the mailbox loop.
cancellationToken CancellationToken
Withdraws the work while it is still queued.
Returns¶
IProtocolActor.PostAsync<T>(Func<T>, CancellationToken) Method¶
Same as PostAsync(Action, CancellationToken) but returns work's result.
System.Threading.Tasks.Task<T> PostAsync<T>(System.Func<T> work, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));
Type parameters¶
T
Parameters¶
The work to run on the mailbox loop.
cancellationToken CancellationToken
Withdraws the work while it is still queued.
Returns¶
IProtocolActor.Schedule(TimeSpan, Action) Method¶
Schedules callback to run on the actor's mailbox loop once delay has elapsed, using event-driven waiting rather than polling (FR-RAW-022) — suitable for STmin waits, timeout checks, and similar periodic/timed protocol tasks. Disposing the returned handle cancels the callback on a best-effort basis: it will not fire if cancellation is observed before it becomes due, but a callback already in flight on the loop may still complete.
Parameters¶
delay TimeSpan
callback Action
Returns¶
Events¶
IProtocolActor.BackgroundExceptionOccurred Event¶
Raised whenever a posted work item (via Post(Action)) or a scheduled callback (via Schedule(TimeSpan, Action)) throws — the actor's single, defined channel for background exceptions (FR-RAW-023). The mailbox loop keeps running afterward; one failing item never stops the actor. Never raised for PostAsync(Action, CancellationToken)/ PostAsync<T>(Func<T>, CancellationToken) failures, which surface through their own returned task instead.
Those reports are raised on the loop, as part of the callback that failed, so a
subscriber may touch the protocol instance's single-writer state there. A report about
the actor's own shutdown is the exception: ProtocolActor reports a
IDisposable.Dispose that gave up waiting for the loop
(TimeoutException) on the thread that called Dispose, while the
loop is still inside the callback that would not finish. In the task-based execution
modes it also reports a loop that failed outside every callback: on that thread too,
or, when the loop fails only after Dispose gave up on it, on the thread the loop
ended on, after its callbacks. A subscriber that mutates loop-owned state must not do
so from those reports.