Understand asynchronous aspect behavior
masterWhen applying aspects to async methods, note the following lifecycle differences:
- OnEntry: Runs on the main thread when the method is first called.
- OnExit: Runs when the method returns its
Taskto the caller, not necessarily when the asynchronous work completes. To run code when the work actually finishes, usetask.ContinueWithinsideOnExit. - OnException: Triggered if the method throws, returns null (causing a
NullReferenceExceptionon await), or returns a faulted task. This may occur long afterOnExithas run.
Tip: Because OnExit and OnException can overlap or run in unexpected orders in async contexts, use MethodExecutionTag to track if OnExit has already executed to avoid duplicate logic in OnException.
// Pattern to ensure OnException only runs if OnExit hasn't
public sealed class LogAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
args.MethodExecutionTag = false;
}
public override void OnExit(MethodExecutionArgs args)
{
args.MethodExecutionTag = true;
}
public override void OnException(MethodExecutionArgs args)
{
if ((bool)args.MethodExecutionTag) return;
// Handle exception...
}
}