| Severity | Error |
| Reported by | PostSharp.Patterns.Common |
| Message | Cannot call "<Method>" from "<Caller>" because the calling method is an anonymous async method. Move the call to a named async method. |
Cause
When an async method opens a custom activity with the OpenActivity method of LogLevelSource, or with the OpenActivity and OpenAsyncActivity methods of the legacy Logger class, PostSharp adds an aspect to this method that tracks when the method is suspended at an await expression and when it resumes, so that the activity follows the asynchronous flow of the method. PostSharp can only instrument a method that it can select as an aspect target. The compiler generates the method of a lambda or of an anonymous method, so PostSharp cannot instrument it and reports COM011.
<Method> is the method that opens the activity. <Caller> is the anonymous method, named after the method that contains it followed by .Anonymous. The message has no file location.
In the following example, an async lambda in ImportAsync opens an activity.
using System;
using System.Threading.Tasks;
using PostSharp.Patterns.Diagnostics;
using static PostSharp.Patterns.Diagnostics.FormattedMessageBuilder;
namespace Errors.COM011_Error;
public class OrderImporter
{
private static readonly LogSource logSource = LogSource.Get();
public Task ImportAsync( int orderId )
{
// The activity is opened in an async lambda.
Func<Task> import = async () =>
{
using ( var activity = logSource.Default.OpenActivity( Formatted( "Importing order {OrderId}", orderId ) ) )
{
await Task.Delay( 10 );
activity.SetSuccess();
}
};
return import();
}
}
public static class Program
{
public static async Task Main()
{
await new OrderImporter().ImportAsync( 42 );
Console.WriteLine( "Order imported." );
}
}
error COM011: COM011_Error.cs(12,17): Cannot call "PostSharp.Patterns.Diagnostics.Custom.LogLevelSource.OpenActivity``1(``0@, PostSharp.Patterns.Diagnostics.OpenActivityOptions@)" from "Errors.COM011_Error.OrderImporter.ImportAsync(System.Int32).Anonymous" because the calling method is an anonymous async method. Move the call to a named async method.
Resolution
Move the code that opens the activity from the lambda or the anonymous method to a named async method, and call this method instead.
In the following example, ImportAsync is itself the async method that opens the activity.
using System;
using System.Threading.Tasks;
using PostSharp.Patterns.Diagnostics;
using static PostSharp.Patterns.Diagnostics.FormattedMessageBuilder;
namespace Errors.COM011_Fixed;
public class OrderImporter
{
private static readonly LogSource logSource = LogSource.Get();
// The activity is opened in a named async method.
public async Task ImportAsync( int orderId )
{
using ( var activity = logSource.Default.OpenActivity( Formatted( "Importing order {OrderId}", orderId ) ) )
{
await Task.Delay( 10 );
activity.SetSuccess();
}
}
}
public static class Program
{
public static async Task Main()
{
await new OrderImporter().ImportAsync( 42 );
Console.WriteLine( "Order imported." );
}
}
Order imported.
See Also
Reference
Other Resources