Table of Contents

Class NDScopedAsyncAttribute

Namespace
NumSharp
Assembly
NumSharp.dll

The ASYNC counterpart of NDScopedAttribute: marks an async method, an async iterator, or a non-async method returning Task/ValueTask[<T>] as an NDScope boundary. At build time the NumSharp IL weaver (tools/NumSharp.Build, shipped to consumer projects as the NumSharp.Build NuGet package) weaves the method's compiler STATE MACHINE — or, for a non-async Task-returning body, its DEFERRAL egress — so the NDArray temporaries it drops are reclaimed at the invocation's completion instead of waiting on the finalizer, with the source keeping its 100% original body exactly as NDScopedAttribute does for synchronous ones.

[AttributeUsage(AttributeTargets.Method|AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class NDScopedAsyncAttribute : Attribute
Inheritance
NDScopedAsyncAttribute
Inherited Members

Remarks

What this attribute covers (the shapes that suspend across await, or defer disposal to a task's completion — everything that needs the async scope seam):

  • Async methodsTask/Task<T>/ValueTask/ ValueTask<T>/void, and any custom [AsyncMethodBuilder] task-like.
  • Async iteratorsIAsyncEnumerable<T> (await + yield return).
  • Non-async methods returning Task/ValueTask[<T>] — e.g. Task<NDArray> M() => ComputeAsync();.

How the weave works. The attributed method is a compiler-generated stub; the real code — and every egress — lives in the state machine's MoveNext. The weaver gives it ONE scope for the whole logical invocation (held in a weaver-added state-machine field), UNINSTALLED before each await's continuation is scheduled and re-installed on whatever thread resumes — so temps stay alive while an awaited callee still uses them, and everything is reclaimed at SetResult/SetException (async), at the final MoveNext (async iterators), with results and yield returned elements routed through the same Returns/YieldTo egress. A NON-async method returning Task/ValueTask yields a completed task's result immediately and DEFERS the scope's disposal to an incomplete task's completion (the in-flight callee may still hold tracked temps); an incomplete ValueTask is Preserve()d — the caller receives the multi-observable form.

SYNCHRONOUS iterators stay on NDScopedAttribute. An IEnumerable<T>/IEnumerator<T> (yield return without await) also compiles to a state machine and uses the same invocation-scope seam, but it is not asynchronous — it is woven by [NDScoped]. Marking a synchronous iterator [NDScopedAsync] is a build ERROR (NDW010); marking an async method, async iterator, or Task-returning method [NDScoped] is the mirror-image ERROR (NDW009). Each error names the correct attribute — a method has exactly one scoping model, and choosing the wrong attribute never silently ships an unwoven method.

The weaver REJECTS (build error NDW003) a shape whose egress it cannot see — an UNSUPPORTED carrier (a bespoke reference type, a collection, or a result struct that does NOT implement INDArrayCarrier) as the async RESULT or as the T inside a Task<T>; scope those by hand (NDW004 = an unrecognized, non-C# state-machine shape; NDW008 = the referenced NumSharp predates the async seam).

A method whose body already opens an NDScope is skipped (idempotence).

Inherited by overrides and implementations exactly like NDScopedAttribute: on a virtual, abstract or interface member it is the contract every override/implementation is woven under (an async override of a non-async Task-returning declaration, or the reverse, each weave through their own shape — the attribute names the model, the override supplies the body). An override's own [NDScoped]/[NDScopedAsync]/[NDScopedCovered] wins over the inherited one; a body-less attributed declaration is the contract, not an NDW005.

PUBLIC because the attribute is consumer-facing: a project that installs the NumSharp.Build package marks its own async/Task composition methods with it. Without the package the attribute is inert metadata — the method runs unscoped, the pre-weave finalizer-backstop behaviour.