IAsyncInterceptor stuck in recursive loop

179 Views Asked by At

I'm following an approach to intercept a simple method asynchronously: https://github.com/wswind/Learn-AOP/blob/master/AutofacAsyncInterceptor/CallLoggerAsyncInterceptor.cs

For the sake of this question, a reduced version of this code could be:

private async Task<TResult> InternalInterceptAsynchronous<TResult>(IInvocation invocation)
{
    // do some async stuff
    // invoke the original method
    invocation.Proceed();
    var task = (Task<TResult>)invocation.ReturnValue;
    var result = await task;
    return result;
}

I did think prior to implementing this that it'd be recursive - since invocation.Proceed() would then be intercepted again, which would itself invoke the Proceed() again, and so on and so forth.

I've seen many recommendations on SO of this library, and it's widely accepted as an approach to intercepting async, what am I missing that would make this method not recursive? It's stuck in an infinite loop, but to me that's expected.

Edit

I discovered what this is, narrowed it down to the 'async stuff' being something like the following:

await MyAsyncMethod();

When MyAsyncMethod is:

public async Task MyAsyncMethod()
{
   // await somethingElse();
}

When I'm awaiting a task that then itself awaits, it breaks invocation.Proceed() and I'm stuck in a loop.

Any help on this greatly appreciated!

1

There are 1 best solutions below

0
victor.x.qu On

also can try https://fs7744.github.io/Norns.Urd/index.html

it use simple way to support async

public class AddTenInterceptorAttribute : AbstractInterceptorAttribute
{
    public override void Invoke(AspectContext context, AspectDelegate next)
    {
        next(context);
        AddTen(context);
    }

    private static void AddTen(AspectContext context)
    {
        if (context.ReturnValue is int i)
        {
            context.ReturnValue = i + 10;
        }
        else if(context.ReturnValue is double d)
        {
            context.ReturnValue = d + 10.0;
        }
    }

    public override async Task InvokeAsync(AspectContext context, AsyncAspectDelegate next)
    {
        await next(context);
        AddTen(context);
    }
}


[AddTenInterceptor]
public interface IGenericTest<T, R> : IDisposable
{
    // or
    //[AddTenInterceptor]
    T GetT();
}