|
OpenCV for Unity 3.0.4
Enox Software / Please refer to OpenCV official document ( http://docs.opencv.org/5.0/index.html ) for the details of the argument of the method.
|
Shared helpers for captured main-thread affinity and marshaling in host-integrated SourceToMat grabbers. More...
Static Public Member Functions | |
| static Task | EnsureCapturedMainThreadAsync (int mainThreadId, SynchronizationContext mainThreadContext, CancellationToken cancellationToken) |
| Waits until execution is on the captured main thread identified by mainThreadId . | |
| static bool | IsCapturedMainThreadId (int mainThreadId) |
| Returns whether the current Thread.ManagedThreadId matches the captured main thread. | |
| static SynchronizationContext | ResolveCapturedSynchronizationContext (int mainThreadId, SynchronizationContext capturedMainThreadContext) |
Resolves the SynchronizationContext used for grabber OpenAsync host-loop waits. | |
| static Task | RunOnCapturedMainThreadAsync (int mainThreadId, SynchronizationContext mainThreadContext, Action action, CancellationToken cancellationToken) |
| Runs action on the captured main thread. | |
| static async Task | YieldCapturedSynchronizationContextAsync (SynchronizationContext mainThreadContext, CancellationToken cancellationToken) |
| Yields until the captured SynchronizationContext processes one posted continuation. | |
Shared helpers for captured main-thread affinity and marshaling in host-integrated SourceToMat grabbers.
Two layers after ConfigureAwait(false):
| Layer | Symptom and API |
|---|---|
| 1 — Marshaling | The managed thread id may already match the captured main thread, but SynchronizationContext.Current no longer matches the captured context. Post-based waits can deadlock on single-threaded hosts. Use EnsureCapturedMainThreadAsync and RunOnCapturedMainThreadAsync (thread-id-first). These APIs do not restore SynchronizationContext.Current and do not advance the host message loop. |
| 2 — Host loop | Bare Task.Yield does not advance host state that updates once per message-loop tick. Use ResolveCapturedSynchronizationContext, SourceToMatSynchronizationContextScope, and host-loop ticks via SourceToMatHostWait or YieldCapturedSynchronizationContextAsync inside the scope. |
Wait loops: Do not write timeout while loops by hand. Use SourceToMatHostWait.WaitUntilOnHostLoopAsync (loop contract: SourceToMatWait). This type is the marshaling and one-tick yield primitive; SourceToMatHostWait owns host-loop predicate waits.
Host-integrated grabbers: capture Thread.ManagedThreadId and SynchronizationContext.Current in the constructor on the host main thread. Use RunOnCapturedMainThreadAsync for short host API work outside host-loop waits (for example CloseAsync; scope is not required for close). When OpenAsync depends on the message loop, await EnsureCapturedMainThreadAsync (Layer 1), resolve context with ResolveCapturedSynchronizationContext, then wrap the full Open body in SourceToMatSynchronizationContextScope (Layer 2).
Product-specific Open sequences (which events to wait on, permission prompts, GPU readiness, and similar) belong in host integration documentation for your runtime (not in Extensions). This type documents only shared marshaling and host-loop primitives.
Anti-patterns:
|
static |
Waits until execution is on the captured main thread identified by mainThreadId .
Layer 1 (marshaling) only. Does not restore SynchronizationContext.Current and does not advance the host message loop. Pair with SourceToMatSynchronizationContextScope for host-loop waits in OpenAsync.
When the current managed thread id already matches, completes immediately without posting, even if SynchronizationContext.Current differs. Otherwise posts to mainThreadContext when available. After this task completes, the awaiter continuation may still run off the captured synchronization context.
| mainThreadId | Managed thread id of the captured main thread. |
| mainThreadContext | Synchronization context captured on the main thread; may be null. |
| cancellationToken | Token used to cancel the wait. |
|
static |
Returns whether the current Thread.ManagedThreadId matches the captured main thread.
Used by thread-id-first grabber marshaling (RunOnCapturedMainThreadAsync, EnsureCapturedMainThreadAsync). This check does not validate SynchronizationContext.Current.
| mainThreadId | Managed thread id captured on the host main thread. |
true when the ids match; otherwise false.
|
static |
Resolves the SynchronizationContext used for grabber OpenAsync host-loop waits.
Call at the start of grabber OpenAsync after Layer 1 marshaling. Pass the result to SourceToMatSynchronizationContextScope and YieldCapturedSynchronizationContextAsync instead of using the raw constructor capture when ConfigureAwait(false) may have run.
Prefer the context captured in the grabber constructor on the host main thread. When that capture is null but execution is already on the captured main thread (for example after EnsureCapturedMainThreadAsync), falls back to SynchronizationContext.Current.
Re-apply SourceToMatSynchronizationContextScope before a host-loop yield when an await inside the Open body may clear SynchronizationContext.Current (for example nested permission polling).
| mainThreadId | Managed thread id captured on the host main thread. |
| capturedMainThreadContext | Synchronization context captured on the main thread; may be null. |
null when none is available.
|
static |
Runs action on the captured main thread.
Layer 1 (marshaling) only. Typical use: grabber CloseAsync and other short host API work that does not wait across host-loop ticks. Does not restore SynchronizationContext.Current.
When the current managed thread id already matches, runs action synchronously without posting, even if SynchronizationContext.Current differs. Otherwise posts to mainThreadContext so host APIs are safe.
| mainThreadId | Managed thread id of the captured main thread. |
| mainThreadContext | Synchronization context captured on the main thread when the grabber was constructed. |
| action | The action to run on the main thread. |
| cancellationToken | Token used to cancel before the action runs. |
|
static |
Yields until the captured SynchronizationContext processes one posted continuation.
Layer 2 — host-loop tick. One message-loop advance via the captured SynchronizationContext. Used by SourceToMatHostWait each iteration (predicate polling and event-driven outer waits on tcs.Task.IsCompleted).
Call inside SourceToMatSynchronizationContextScope (or a nested scope when an inner await may clear SynchronizationContext.Current) while on the captured main thread so posting does not deadlock on single-threaded hosts. Pass the context from ResolveCapturedSynchronizationContext. When mainThreadContext is null, falls back to Task.Yield, which does not satisfy Layer 2 after ConfigureAwait(false).
For predicate loops with timeout, prefer SourceToMatHostWait.WaitUntilOnHostLoopAsync instead of a hand-written while around this method.
| mainThreadContext | Synchronization context captured on the host main thread; when null, falls back to Task.Yield. |
| cancellationToken | Token used to cancel the wait. |