Open sandboxFocusImprove this doc

LA0185: Method Interception Aspect Without OnInvokeAsync on an Async Method

Severity Warning
Reported by PostSharp
Message Semantic advising for the "<Aspect>" aspect is enabled for the "<Method>" method, but the OnInvokeAsync advice is not implemented. To suppress this message either implement the OnInvokeAsync method or set the SemanticallyAdvisedMethodKinds property of the aspect to 'None'.

Cause

A MethodInterceptionAspect intercepts an async method, or a method returning an awaitable type such as Task, with its OnInvokeAsync(MethodInterceptionArgs) method, which can await the end of the task. This is called semantic advising, and it is enabled by default by the SemanticallyAdvisedMethodKinds property of the aspect.

When the aspect does not override OnInvokeAsync(MethodInterceptionArgs), PostSharp falls back to OnInvoke(MethodInterceptionArgs), and reports LA0185. Proceed() then returns as soon as the method returns its task, at the first await that does not complete synchronously, so the code after it runs before the asynchronous operation ends.

In the following example, the [Log] aspect implements only OnInvoke, and is applied to the async method ShipAsync.

using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.LA0185_Error;

[PSerializable]
public class LogAttribute : MethodInterceptionAspect
{
    public override void OnInvoke( MethodInterceptionArgs args )
    {
        Console.WriteLine( $"Entering {args.Method.Name}" );
        args.Proceed();
        Console.WriteLine( $"Leaving {args.Method.Name}" );
    }
}

public class OrderService
{
    // The aspect intercepts this async method with OnInvoke, because it does not implement OnInvokeAsync.
    [Log]
    public async Task ShipAsync( int orderId )
    {
        Console.WriteLine( $"Preparing order {orderId}" );
        await Task.Delay( 10 );
        Console.WriteLine( $"Shipped order {orderId}" );
    }
}

public static class Program
{
    public static async Task Main()
    {
        await new OrderService().ShipAsync( 42 );
    }
}
warning LA0185: LA0185_Error.cs(23,23): Semantic advising for the "Errors.LA0185_Error.LogAttribute" aspect is enabled for the "Errors.LA0185_Error.OrderService.ShipAsync(System.Int32)" method, but the OnInvokeAsync advice is not implemented. To suppress this message either implement the OnInvokeAsync method or set the SemanticallyAdvisedMethodKinds property of the aspect to 'None'.

The program shows that the aspect leaves the method before the order is shipped:

Entering ShipAsync
Preparing order 42
Leaving ShipAsync
Shipped order 42

Resolution

In the following example, the aspect overrides OnInvokeAsync, which awaits the end of ShipAsync.

using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Serialization;

namespace Errors.LA0185_Fixed;

[PSerializable]
public class LogAttribute : MethodInterceptionAspect
{
    public override void OnInvoke( MethodInterceptionArgs args )
    {
        Console.WriteLine( $"Entering {args.Method.Name}" );
        args.Proceed();
        Console.WriteLine( $"Leaving {args.Method.Name}" );
    }

    // OnInvokeAsync intercepts async methods and awaits the end of the task.
    public override async Task OnInvokeAsync( MethodInterceptionArgs args )
    {
        Console.WriteLine( $"Entering {args.Method.Name}" );
        await args.ProceedAsync();
        Console.WriteLine( $"Leaving {args.Method.Name}" );
    }
}

public class OrderService
{
    [Log]
    public async Task ShipAsync( int orderId )
    {
        Console.WriteLine( $"Preparing order {orderId}" );
        await Task.Delay( 10 );
        Console.WriteLine( $"Shipped order {orderId}" );
    }
}

public static class Program
{
    public static async Task Main()
    {
        await new OrderService().ShipAsync( 42 );
    }
}
Entering ShipAsync
Preparing order 42
Shipped order 42
Leaving ShipAsync

See Also

Reference

MethodInterceptionAspect
SemanticallyAdvisedMethodKinds

Other Resources

Semantic Advising of Iterator and Async Methods