ParagonSynchronizationContext

Custom SynchronizationContext that replaces Unity's default. Routes async/await continuations to specific frame phases (Update, LateUpdate, FixedUpdate) via dedicated WorkRunner queues, and provides editor-mode async support with a throttled editor update runner. Installs itself automatically at both editor load and runtime initialization.

Definition

Namespace: Paragon.Core.Async Assembly: Paragon.dll

internal sealed class ParagonSynchronizationContext : SynchronizationContext

Inherits: System.Threading.SynchronizationContext Visibility: internal — not directly accessible by game code. Use the Yield API instead.

Remarks

Unity's default UnitySynchronizationContext posts all continuations to a single queue processed during Update. ParagonSynchronizationContext improves on this by:

  1. Phase-specific routing — Continuations can target Update, LateUpdate, or FixedUpdate via WorkExecutionTime.

  2. Editor support — A separate editorUpdateRunner processes async work in edit mode (not just Play Mode), throttled to 50ms ticks via EditorApplication.update.

  3. Build safety — Automatically restores Unity's default context during compilation and builds, then re-installs afterward. This prevents async continuations from interfering with the build pipeline.

Installation Lifecycle

Phase
Hook
What Happens

Editor load

[InitializeOnLoadMethod]

Creates context, subscribes to editor events

Runtime start

[RuntimeInitializeOnLoadMethod]

Creates context (if not already), injects PlayerLoopSystem entries

Compilation start

CompilationPipeline.compilationStarted

Restores Unity default context

Compilation end

CompilationPipeline.compilationFinished

Re-installs Paragon context

Build start

BuildPlayerProcessor.PrepareForBuild

Restores Unity default context

Build end

IPostprocessBuildWithReport

Re-installs Paragon context

Play mode exit

PlayModeStateChange.EnteredEditMode

Clears all runners

Application quit

Application.quitting

Clears all runners

PlayerLoop Injection

The context injects three custom loops into Unity's PlayerLoopSystem:

Custom Loop
Injected Into
Order
Runner

SynchronizationContextUpdate

PreUpdate

Append

updateRunner

SynchronizationContextLateUpdate

PreLateUpdate

Append

lateUpdateRunner

SynchronizationContextFixedUpdate

FixedUpdate

Prepend

fixedUpdateRunner

Quick Lookup

Goal
How

Post work to Update phase

context.Post(callback, WorkExecutionTime.UPDATE)

Post work to LateUpdate

context.Post(callback, WorkExecutionTime.LATE_UPDATE)

Post work to FixedUpdate

context.Post(callback, WorkExecutionTime.FIXED_UPDATE)

Send synchronously (main thread)

context.Send(callback, state) — executes inline

Send synchronously (background thread)

context.Send(callback, state) — queues and blocks

circle-info

Game code should not access ParagonSynchronizationContext directly — it is internal. Use the Yield static API for all async frame-waiting operations.

Methods

Send

Synchronous send. If called from the main thread, executes the callback immediately. If called from a background thread, enqueues a WorkRequest with a ManualResetEvent and blocks until execution completes on the main thread.

Parameter
Type
Description

callback

SendOrPostCallback

Delegate to execute

state

object

State passed to the callback

Post (Standard)

Asynchronous post. Queues work to the updateRunner (in Play Mode) or editorUpdateRunner (in Edit Mode). This is the override called by the C# async/await machinery.

Parameter
Type
Description

callback

SendOrPostCallback

Delegate to execute

state

object

State passed to the callback

Post (Phase-Specific)

Extended post that routes work to a specific frame phase based on WorkExecutionTime.

Parameter
Type
Description

callback

Action

Delegate to execute

executionTime

WorkExecutionTime

Target frame phase

circle-info

In Edit Mode (not playing, not quitting), all work is routed to editorUpdateRunner regardless of the specified executionTime. This ensures editor async code works without the player loop running.

OperationStarted / OperationCompleted

Thread-safe operation count tracking via Interlocked.Increment / Decrement.

Common Pitfalls

circle-exclamation
circle-exclamation
circle-exclamation

See Also

Last updated