Both the compliant and noncompliant examples are missing the async modifier for the function. That is what determines if the method should be suffixed with Async or not.
current compliant example
public class Foo
{
public Task ReadAsync(byte [] buffer, int offset, int count, CancellationToken cancellationToken)
}
what it should be
public class Foo
{
public async Task ReadAsync(byte [] buffer, int offset, int count, CancellationToken cancellationToken) {}
}
… though even this is strange as the method name is Read but this doesnt return the result of reading anything.
So what looks like is that this rule has referenced the example code that is incorrect, and not the section that states the rule.
Asynchronous methods in TAP include the Async suffix after the operation name for methods that return awaitable types, such as Task, Task, ValueTask, and ValueTask. For example, an asynchronous Get operation that returns a Task<String> can be named GetAsync
According to the msft docs that you also cited, the method should have an Async suffix if it returns an awaitable type. The current compliant example demonstrates that. So, I would say the rule is aligned with the msft docs.
The current compliant example is missing the async keyword. The presence of that keyword is what determines if the method is async or not. The return type from the function has nothing to do with async, but you can’t have an awaitable type without the async keyword.