| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot apply the advice "<Advice>" to target "<Method>": async interception can be applied only to methods that return Task or Task<T> and have no by-reference parameter. Add a non-async OnMethodInvokeAdvice to the group and, if the method returns an awaitable type, set the UnsupportedTargetAction property of the master advice to Fallback, or to Ignore to skip the method. |
Cause
An advice marked with OnMethodInvokeAsyncAdvice intercepts the task that a method returns, and supports only the methods that return a Task or a Task<TResult> and have no ref or out parameter. PostSharp reports LA0172 on the target method in the following cases:
- The method is
async void, or returns another awaitable type, such as ValueTask<TResult>, or a task with a by-reference parameter, and the UnsupportedTargetAction property of the master advice of the group keeps its default value, Fail. - The method is not advised semantically, for example a method that returns
voidor a value, and the group of the advice has no advice marked with OnMethodInvokeAdvice to intercept it. The UnsupportedTargetAction property does not suppress the error in this case.
<Advice> is the advice method, and <Method> is the target method.
In the following example, the [Log] aspect has only an async interception advice, and it is applied to a method that returns a ValueTask<decimal>.
using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0172_Error;
[PSerializable]
public class LogAttribute : MethodLevelAspect
{
[OnMethodInvokeAsyncAdvice]
public async Task OnInvokeAsync( MethodInterceptionArgs args )
{
Console.WriteLine( $"Calling {args.Method.Name} asynchronously." );
await args.ProceedAsync();
}
}
public class PriceService
{
// Async interception does not support methods that return ValueTask<T>.
[Log]
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 LA0172: LA0172_Error.cs(24,37): Cannot apply the advice "Errors.LA0172_Error.LogAttribute.OnInvokeAsync(PostSharp.Aspects.MethodInterceptionArgs)" to target "Errors.LA0172_Error.PriceService.GetPriceAsync(System.String)": async interception can be applied only to methods that return Task or Task<T> and have no by-reference parameter. Add a non-async OnMethodInvokeAdvice to the group and, if the method returns an awaitable type, set the UnsupportedTargetAction property of the master advice to Fallback, or to Ignore to skip the method.
Resolution
- Make the target method return a Task or a Task<TResult>, without
reforoutparameters. - Add an advice marked with OnMethodInvokeAdvice to the group, and set the UnsupportedTargetAction property of the master advice to Fallback, so that the non-async advice intercepts the unsupported methods (see LA0173).
- Set the property to Ignore to skip the
async voidmethods and the methods that return another awaitable type. - Do not apply the aspect to the method.
In the following example, the method returns a Task<decimal>, which the advice intercepts.
using System;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0172_Fixed;
[PSerializable]
public class LogAttribute : MethodLevelAspect
{
[OnMethodInvokeAsyncAdvice]
public async Task OnInvokeAsync( MethodInterceptionArgs args )
{
Console.WriteLine( $"Calling {args.Method.Name} asynchronously." );
await args.ProceedAsync();
}
}
public class PriceService
{
// The method returns a Task<T>, which async interception supports.
[Log]
public async Task<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 asynchronously.
9.0
See Also
Reference
OnMethodInvokeAsyncAdvice
OnMethodInvokeAdvice
UnsupportedTargetAction
Other Resources
Advice Methods
Semantic Advising of Iterator and Async Methods