| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot apply the aspect "<Aspect>" to target "<Target>": async interception supports only methods that return Task or Task<T>. To intercept other methods, the aspect must implement OnInvoke; when it does, set the UnsupportedTargetAction property of the aspect to Fallback to intercept this method with OnInvoke, or to Ignore to skip it. |
Cause
When a MethodInterceptionAspect overrides OnInvokeAsync, PostSharp intercepts async methods with this advice, which awaits the Task or Task<TResult> of the method. Async interception does not support the other async methods: those that return void, and those that return another awaitable type, such as ValueTask or ValueTask<TResult>. PostSharp reports LA0166 in these cases:
- The target is such an async method, and the UnsupportedTargetAction of the aspect is
Fail, its default value. - The aspect overrides
OnInvokeAsyncbut not OnInvoke, and the target is a method that async interception does not support, async or not. WithoutOnInvoke, the aspect has no other way to intercept the method.
In the following example, the [Log] aspect is applied to an async method that returns a ValueTask<decimal>.
using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Serialization;
namespace Errors.LA0166_Error;
[PSerializable]
public class LogAttribute : MethodInterceptionAspect
{
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
{
// This async method returns a ValueTask, which async interception does not support.
[Log]
public async ValueTask<decimal> GetPriceAsync( string product )
{
await Task.Yield();
return product.Length * 10m;
}
}
public static class Program
{
public static async Task Main()
{
decimal price = await new PriceService().GetPriceAsync( "Chair" );
Console.WriteLine( $"Price: {price}" );
}
}
error LA0166: LA0166_Error.cs(28,37): Cannot apply the aspect "Errors.LA0166_Error.LogAttribute" to target "Errors.LA0166_Error.PriceService.GetPriceAsync(System.String)": async interception supports only methods that return Task or Task<T>. To intercept other methods, the aspect must implement OnInvoke; when it does, set the UnsupportedTargetAction property of the aspect to Fallback to intercept this method with OnInvoke, or to Ignore to skip it.
Resolution
- When the aspect overrides
OnInvoke, set the UnsupportedTargetAction property of the aspect: - When the aspect overrides only
OnInvokeAsync, overrideOnInvoketoo, or do not apply the aspect to the method. SettingUnsupportedTargetActionalone does not help:Fallbackreports LA0171 because there is no advice to fall back to. - Make the method return a Task or a Task<TResult>.
In the following example, the aspect falls back to OnInvoke for GetPriceAsync.
using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Serialization;
namespace Errors.LA0166_Fixed;
[PSerializable]
public class LogAttribute : MethodInterceptionAspect
{
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
{
// The aspect falls back to OnInvoke, which intercepts the call that returns the ValueTask.
[Log( UnsupportedTargetAction = UnsupportedTargetAction.Fallback )]
public async ValueTask<decimal> GetPriceAsync( string product )
{
await Task.Yield();
return product.Length * 10m;
}
}
public static class Program
{
public static async Task Main()
{
decimal price = await new PriceService().GetPriceAsync( "Chair" );
Console.WriteLine( $"Price: {price}" );
}
}
Calling GetPriceAsync.
Price: 50
See Also
Reference
MethodInterceptionAspect
UnsupportedTargetAction
UnsupportedTargetAction
Other Resources
Intercepting Methods
Semantic Advising of Iterator and Async Methods