| Severity | Error |
| Reported by | PostSharp |
| Message | Incorrect type of the [FlowBehavior] parameter in "<Advice>". The parameter must be passed by reference and be of type "PostSharp.Aspects.FlowBehavior". |
Cause
An advice changes the control flow of the target method by setting a parameter annotated with FlowBehaviorAttribute, for instance to FlowBehavior.Return or FlowBehavior.Yield. The woven code reads the value after the advice returns, so the parameter must be passed by reference, as out or ref, and be of type FlowBehavior. PostSharp reports LA0155 when the parameter is passed by value or has another type, such as int. A value set to a parameter passed by value would be lost when the advice returns.
In the following example, the [SwitchToThreadPool] aspect receives the flow behavior by value.
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0155_Error;
[PSerializable]
public class SwitchToThreadPoolAttribute : MethodLevelAspect
{
[OnMethodEntryAdvice]
public void OnEntry( [Awaiter] out YieldAwaitable.YieldAwaiter awaiter,
// The flow behavior is passed by value, so the value that the advice sets is lost.
[FlowBehavior] FlowBehavior flowBehavior )
{
Console.WriteLine( "Switching to the thread pool." );
awaiter = Task.Yield().GetAwaiter();
flowBehavior = FlowBehavior.Yield;
}
}
public class ReportService
{
[SwitchToThreadPool]
public async Task GenerateAsync()
{
Console.WriteLine( "Generating the report." );
await Task.CompletedTask;
}
}
public static class Program
{
public static void Main()
{
new ReportService().GenerateAsync().Wait();
}
}
error LA0155: LA0155_Error.cs(16,54): Incorrect type of the [FlowBehavior] parameter in "Errors.LA0155_Error.SwitchToThreadPoolAttribute.OnEntry(System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter@, PostSharp.Aspects.FlowBehavior)". The parameter must be passed by reference and be of type "PostSharp.Aspects.FlowBehavior".
Resolution
Declare the [FlowBehavior] parameter as out FlowBehavior, and assign it on every path of the advice. Use ref FlowBehavior when the advice may leave the value unchanged.
In the following example, the flow behavior is an out parameter.
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Serialization;
namespace Errors.LA0155_Fixed;
[PSerializable]
public class SwitchToThreadPoolAttribute : MethodLevelAspect
{
[OnMethodEntryAdvice]
public void OnEntry( [Awaiter] out YieldAwaitable.YieldAwaiter awaiter,
// The flow behavior is an out parameter, which the advice assigns.
[FlowBehavior] out FlowBehavior flowBehavior )
{
Console.WriteLine( "Switching to the thread pool." );
awaiter = Task.Yield().GetAwaiter();
flowBehavior = FlowBehavior.Yield;
}
}
public class ReportService
{
[SwitchToThreadPool]
public async Task GenerateAsync()
{
Console.WriteLine( "Generating the report." );
await Task.CompletedTask;
}
}
public static class Program
{
public static void Main()
{
new ReportService().GenerateAsync().Wait();
}
}
Switching to the thread pool.
Generating the report.
See Also
Reference
FlowBehaviorAttribute
FlowBehavior
Other Resources