Does the use of the “Async” suffix in a method name depend on whether the ‘async’ modifier is used?

I think the truth is ambiguous even from Microsoft documentation:

In Visual Studio 2012 and the .NET Framework 4.5, any method that is
attributed with the async keyword (Async in Visual Basic) is
considered an asynchronous method, and the C# and Visual Basic
compilers perform the necessary transformations to implement the
method asynchronously by using TAP. An asynchronous method should
return either a Task or a Task<TResult> object.

http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx

That’s not right already. Any method with async is asynchronous and then its saying it should return either a Task or Task<T> – which isn’t right for methods at the top of a call stack, Button_Click for example, or async void.

Of course, you have to consider what is the point of the convention?

You could say that the Async suffix convention is to communicate to the API user that the method is awaitable. For a method to be awaitable, it must return Task for a void, or Task<T> for a value-returning method, which means only the latter can be suffixed with Async.

Or you might say that the Async suffix convention is to communicate that the method can return immediately, relinquishing the current thread to perform other work and potentially causing races.

This Microsoft doc quote says:

By convention, you append “Async” to the names of methods that have an
Async or async modifier.

Content now only available via the Wayback Machine

Which doesn’t even mention that your own asynchronous methods returning Task need the Async suffix, which I think we all agree they do.


So the answer to this question could be: both. In both cases, you need to append Async to methods with async keyword and that return Task or Task<T>.


I’m going to ask Stephen Toub to clarify the situation.

Update

So I did. And here’s what our good man wrote:

If a public method is Task-returning and is asynchronous in nature (as
opposed to a method that is known to always execute synchronously to
completion but still returns a Task for some reason), it should have
an “Async” suffix. That’s the guideline. The primary goal here with
the naming is to make it very obvious to a consumer of the
functionality that the method being invoked will likely not complete
all of its work synchronously; it of course also helps with the case
where functionality is exposed with both synchronous and asynchronous
methods such that you need a name difference to distinguish them. How
the method achieves its asynchronous implementation is immaterial to
the naming: whether async/await is used to garner the compiler’s help,
or whether types and methods from System.Threading.Tasks are used
directly (e.g. TaskCompletionSource) doesn’t really matter, as that
doesn’t affect the method’s signature as far as a consumer of the
method is concerned.

Of course, there are always exceptions to a
guideline. The most notable one in the case of naming would be cases
where an entire type’s raison d’etre is to provide async-focused
functionality, in which case having Async on every method would be
overkill, e.g. the methods on Task itself that produce other Tasks.

As for void-returning asynchronous methods, it’s not desirable to have
those in public surface area, since the caller has no good way of
knowing when the asynchronous work has completed. If you must expose
a void-returning asynchronous method publicly, though, you likely do
want to have a name that conveys that asynchronous work is being
initiated, and you could use the “Async” suffix here if it made sense.
Given how rare this case should be, I’d argue it’s really a
case-by-case kind of decision.

I hope that helps, Steve

The succinct guidance from Stephen’s opening sentence is clear enough. It excludes async void because it is unusual to want to create a public API with such a design since the correct way to implement an asynchronous void is to return a plain Task instance and let the compiler to its magic. However, if you did want a public async void, then appending Async is advised. Other top-of-stack async void methods such as event handlers are usually not public and don’t matter/qualify.

For me, it tells me that if I find myself wondering about suffixing Async on an async void, I probably should turn it into an async Task so that callers can await it, then append Async.

Leave a Comment