Search code examples
c#.net-4.0async-awaitpostsharp

How do I set ApplyToStateMachine?


I'm using PostSharp 5.0.35 for the first time for diagnostic logging in a desktop application. I've added the sample code and called the Initialise method in Program.Main():

using PostSharp.Patterns.Diagnostics;
using PostSharp.Patterns.Diagnostics.Backends.Log4Net;
using PostSharp.Extensibility;

[assembly: Log(
    AttributePriority = 1,
    AttributeTargetMemberAttributes = MulticastAttributes.Protected | MulticastAttributes.Internal | MulticastAttributes.Public
)]
[assembly: Log(
    AttributePriority = 2,
    AttributeExclude = true,
    AttributeTargetMembers = "get_*"
)]

class AspectInitialiser
{
    public void Initialise()
    {
        LoggingServices.DefaultBackend = new Log4NetLoggingBackend();
    }
}

The code won't compile giving the following error message due to the code having async methods in a .NET Framework 4.0 project.

Applying aspects to async state machine is not supported for the current target framework. Please set ApplyToStateMachine property to false when applying an aspect to an async method.

That's fine, but where is this ApplyToStateMachine property? The only documentation I can find assumes I know where the property is already.


Solution

  • I got an official response from PostSharp which has solved the problem.


    Hello,

    I understand that in your project you're using Microsoft.Bcl.Async package that provides support for async in .NET Framework 4.0. The Microsoft.Bcl.Async package is not supported by PostSharp and so async methods cannot be processed in this configuration. Unfortunately, the error message emitted by us is very general and must be improved - the LogAttribute in particular doesn't expose the ApplyToStateMachine property at all.

    As a workaround you can disable the LogAttribute on async methods completely by creating your own derived class and overriding CompileTimeValidate method. The sample below demonstrates this approach.

    public class MyLogAttribute : LogAttribute
    {
        public override bool CompileTimeValidate(MethodBase method)
        {
            // C# compiler marks async methods with AsyncStateMachineAttribute
            if (method.GetCustomAttributes(typeof(AsyncStateMachineAttribute), false).Length > 0)
                return false;
    
            return true;
        }
    }
    

    -alex