| Severity | Error |
| Reported by | PostSharp |
| Message | Aspect "<Aspect>" does not implement the non-async OnInvoke advice, therefore the UnsupportedTargetAction property cannot be set to Fallback. |
Cause
A MethodInterceptionAspect that overrides OnInvokeAsync(MethodInterceptionArgs) intercepts the tasks of the methods that return a Task or a Task<TResult>. Async interception does not support other targets, such as async void methods and methods that return a ValueTask<TResult>. The UnsupportedTargetAction property says what PostSharp does with them, and Fallback means that OnInvoke(MethodInterceptionArgs) intercepts them without async semantics.
PostSharp reports LA0171 when the property is set to Fallback and the aspect does not override OnInvoke(MethodInterceptionArgs): there is nothing to fall back to. PostSharp checks this for every target of the aspect, also for the targets that async interception supports, and reports the error on the target method.
In the following example, the [Log] aspect overrides only OnInvokeAsync, and its usage asks for a fallback.
using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Serialization;
namespace Errors.LA0171_Error;
[PSerializable]
public class LogAttribute : MethodInterceptionAspect
{
public override async Task OnInvokeAsync( MethodInterceptionArgs args )
{
Console.WriteLine( $"Calling {args.Method.Name} asynchronously." );
await args.ProceedAsync();
}
}
public class PriceService
{
// Fallback needs an OnInvoke method, which the aspect does not override.
[Log( UnsupportedTargetAction = UnsupportedTargetAction.Fallback )]
public async ValueTask<decimal> GetPriceAsync( string product )
{
await Task.Yield();
return product.Length * 1.5m;
}
}
public static class Program
{
public static async Task Main()
{
Console.WriteLine( await new PriceService().GetPriceAsync( "Coffee" ) );
}
}
error LA0171: LA0171_Error.cs(22,37): Aspect "Errors.LA0171_Error.LogAttribute" does not implement the non-async OnInvoke advice, therefore the UnsupportedTargetAction property cannot be set to Fallback.
Resolution
- Override OnInvoke(MethodInterceptionArgs) in the aspect, so that PostSharp can intercept the unsupported targets without async semantics.
- Otherwise, set UnsupportedTargetAction to Ignore to leave the unsupported targets alone, or remove the property to get an error on each of them.
In the following example, the aspect overrides OnInvoke, which intercepts the method that returns a ValueTask<decimal>.
using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Serialization;
namespace Errors.LA0171_Fixed;
[PSerializable]
public class LogAttribute : MethodInterceptionAspect
{
// The fallback for the methods that async interception does not support.
public override void OnInvoke( MethodInterceptionArgs args )
{
Console.WriteLine( $"Calling {args.Method.Name}." );
args.Proceed();
}
public override async Task OnInvokeAsync( MethodInterceptionArgs args )
{
Console.WriteLine( $"Calling {args.Method.Name} asynchronously." );
await args.ProceedAsync();
}
}
public class PriceService
{
[Log( UnsupportedTargetAction = UnsupportedTargetAction.Fallback )]
public async ValueTask<decimal> GetPriceAsync( string product )
{
await Task.Yield();
return product.Length * 1.5m;
}
}
public static class Program
{
public static async Task Main()
{
Console.WriteLine( await new PriceService().GetPriceAsync( "Coffee" ) );
}
}
Calling GetPriceAsync.
9.0
See Also
Reference
MethodInterceptionAspect
UnsupportedTargetAction
Other Resources
Intercepting Methods
Semantic Advising of Iterator and Async Methods