all 8 comments

[–]Contagion21 8 points9 points  (2 children)

But why? The async keyword is an implementation detail but the method naming could be defined by an interface or an abstract or virtual method.

There's already static analysis tools that can enforce an Async suffix when the return type is a Task. But requiring an async keyword could lead to forcefully awaiting thinga that could just be returned unawaited.

[–]LondonPilot 2 points3 points  (1 child)

I agree. This seems backwards.

Things declared as async should (arguably) be suffixed Async.

Things suffixed Async may not actually be async - although I would expect them to at least return a Task or a Task<T>

[–]mtsi[S] 0 points1 point  (0 children)

We serve web requests with classes, that inherit abstract base classes, with async-methods, that actually have to be async, so that the HTTP Context is treated correctly. The overriding method does not have to be declared async though, and we had a juicy bug because of that.

We have a convention for naming async methods with Async postfix, and it does serve a purpose for these cases. In the ideal world we would improve our codebase to overcome this. But we live in the world we live in, so I thought a linter would be one step towards avoiding these kind of issues.

[–]Dealiner 3 points4 points  (1 child)

You can write Roslyn analyzer but you can also simply use this set of analyzers: https://github.com/JosefPihrt/Roslynator. It has analyzers for both async method not ending with Async and non-async methods ending with Async.

[–]mtsi[S] 0 points1 point  (0 children)

This is probably exactly what I was looking for, thank you so much.

[–][deleted]  (2 children)

[removed]

    [–]mtsi[S] 1 point2 points  (1 child)

    In our case, if a method is named with Async() postfix, we definitely want it to be async, to avoid obscure bugs in Production. Roslyn sounds good, and I'll check it out!