YieldAwaitable
Internal readonly struct implementing the C# async/await pattern for yielding execution to the ParagonSynchronizationContext. Contains a nested YieldAwaiter struct that posts continuations to the synchronization context at a specified WorkExecutionTime, ensuring they resume on the main thread during the correct Unity update phase.
Definition
Namespace: Paragon.Core.Async Assembly: Paragon.dll
internal readonly struct YieldAwaitable[StructLayout(LayoutKind.Sequential)]
internal readonly struct YieldAwaiter : INotifyCompletionImplements (awaiter): System.Runtime.CompilerServices.INotifyCompletion
Remarks
YieldAwaitable is the low-level mechanism that makes await Yield.WaitForUpdate() work. The Yield class holds a static instance per WorkExecutionTime value and returns it from its WaitFor* methods.
When the C# compiler encounters await yieldAwaitable, it:
Calls
GetAwaiter()→ creates aYieldAwaiterwith the same execution time.Checks
IsCompleted→ always returnsfalse, forcing the continuation to be scheduled (never completes synchronously).Calls
OnCompleted(continuation)→ posts the continuation to theParagonSynchronizationContextwith the specified execution time.Calls
GetResult()→ no-op; exists only to satisfy the compiler pattern.
Fallback Behavior
If the current SynchronizationContext is not a ParagonSynchronizationContext (e.g., in unit tests or non-play editor contexts), the awaiter falls back to the standard SynchronizationContext.Post(). In play mode, this fallback triggers a Debug.Assert to alert developers that the Paragon context is not installed.
Quick Lookup
Create an awaitable
new YieldAwaitable(WorkExecutionTime.UPDATE)
Use in async code
await yieldAwaitable (compiler calls GetAwaiter() automatically)
Choose update phase
Pass the desired WorkExecutionTime to the constructor
YieldAwaitable
Constructor
executionTime
WorkExecutionTime
The Unity update phase at which the continuation should resume
Methods
GetAwaiter
Returns a YieldAwaiter configured with the same execution time. Called by the compiler when this struct is used with await.
Returns: A YieldAwaiter instance.
YieldAwaiter
Constructor
executionTime
WorkExecutionTime
The Unity update phase at which to resume
Properties
IsCompleted
Always returns false — yielding always suspends execution and schedules a continuation. This ensures the continuation is posted to the synchronization context rather than running synchronously.
Methods
OnCompleted
Posts the continuation to the current SynchronizationContext. If the context is ParagonSynchronizationContext, uses the typed Post(Action, WorkExecutionTime) overload to schedule at the correct update phase. Otherwise falls back to the standard Post(SendOrPostCallback, object).
continuation
Action
The async method's continuation to invoke on the main thread
Assertion in play mode fallback If OnCompleted is called in play mode but SynchronizationContext.Current is not a ParagonSynchronizationContext, a Debug.Assert fires. This indicates that the Paragon context was not properly installed during runtime initialization.
GetResult
No-op. Exists solely to satisfy the compiler's awaiter pattern requirements.
Common Pitfalls
IsCompleted is always false Unlike some awaitables that can complete synchronously, YieldAwaitable always forces a suspension. This means every await on a YieldAwaitable will defer to the next occurrence of the specified update phase — there is no fast path.
Context must be ParagonSynchronizationContext in play mode If the Paragon context is not installed (e.g., it was overridden by another plugin), the awaiter falls back to the default SynchronizationContext.Post(), which may not schedule work at the correct update phase. The assertion helps catch this during development.
Examples
How the Compiler Uses YieldAwaitable
See Also
Yield — the public API that uses
YieldAwaitableinternallyParagonSynchronizationContext — receives the posted continuations
WorkRunner — executes the posted continuations at the correct update phase
SynchronizationContext Subsystem — subsystem overview
Last updated