By convention, you append "Async" to the names of methods that have an async modifier. You can ignore the convention where an event, base class, or interface contract suggests a different name. For example, you shouldn't rename common event handlers, such as Button1_Click .
The async keyword turns a method into an async method, which allows you to use the await keyword in its body. When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete. await can only be used inside an async method.
The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.
Async never schedules your method to run on a background thread. The only way to do that is using something like Task. Run , which is explicitly for that purpose. In the case of a UI application, that means the code before the first await runs in the UI thread.
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 aTask
or aTask<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
.
I build a lot API-services and other applications that call others systems where most of my code is running asynchronous.
My own rule of thumb I'm following is:
If there is both non-async and async method that return the same thing I suffix the async one with Async. Otherwise not.
Examples:
Only one method:
public async Task<User> GetUser() { [...] }
Same method with two signatures:
public User GetUser() { [...] }
public async Task<User> GetUserAsync() { [...] }
This makes sense since it's the same data that is returned but the only thing that differs is the way of returning data, not the data itself.
I also think this naming conventions exists due to the need to introduce async methods and still maintain backwards compatibility.
I argue that new code shouldn't use the Async suffix. It is just as obvious as return type of String, or Int as mentioned before in this thread.
What is the convention for suffixing method names with "Async".
The Task-based Asynchronous Pattern (TAP) dictates that methods should always return a Task<T>
(or Task
) and be named with an Async suffix; this is separate from the use of async
. Both Task<bool> Connect()
and async
Task<bool> Connect()
will compile and run just fine, but you won't be following the TAP naming convention.
Should the method contain the
async
modifier, or it enough that it just returns Task?
If the body of the method (regardless of the return type or name) includes await
, you must use async
; and the compiler will tell you "The 'await' operator can only be used within an async method. ...". Returning Task<T>
or Task
is not "enough" to avoid using async
. See async (C# Reference) for details.
I.e. which of these signatures are correct:
Both async
Task<bool> ConnectAsync()
and Task<bool> ConnectAsync()
properly follow the TAP conventions. You could always use the async
keyword, but you'll get a compiler warning "This async method lacks 'await' operators and will run synchronously. ..." if the body doesn't use await
.
or it enough that it just returns Task?
That. The async
keyword isn't the real issue here. If you implement the asynchrony without using the async
keyword the method is still "Async", in the general sense.
I would argue that it should use the Async-suffix if it returns a Task regardless if the method is declared with the async
modifier or not.
The reason behind it being that the name is declared in the interface. The interface declares the return type which is a Task
. Then there are two implementations of that interface, one implementation implements it using the async
modifier, the other does not.
public interface IFoo
{
Task FooAsync();
}
public class FooA : IFoo
{
public Task FooAsync() { /* ... */ }
}
public class FooB : IFoo
{
public async Task FooAsync() { /* ... */ }
}
Since Task
and Task<T>
are both awaitable types, they represent some asynchronous operation. Or at least they should represent.
You should add suffix Async
to a method which, in some cases (not necessarily all), doesn't return a value but rather returns a wrapper around an ongoing operation. That wrapper is usually a Task
, but on Windows RT it can be IAsyncInfo
. Follow your gut feeling and remember that if a user of your code sees the Async
function, he or she will know that the invocation of that method is decoupled from the result of that method and that they need to act accordingly.
Note that there are methods such as Task.Delay
and Task.WhenAll
which return Task
and yet don't have the Async
suffix.
Also note that there are async void
methods which represent fire and forget asynchronous method and you should better be aware that the method is built in such way.
In Asynchronous Programming with async and await (C#), Microsoft offers the following guidance:
Naming Convention
By convention, you append "Async" to the names of methods that have an async modifier.
You can ignore the convention where an event, base class, or interface contract suggests a different name. For example, you shouldn’t rename common event handlers, such as
Button1_Click
.
I find this guidance incomplete and unsatisfying. Does this mean that in the absence of the async
modifier, this method should be named Connect
instead of ConnectAsync
?
public Task<bool> ConnectAsync()
{
return ConnectAsyncInternal();
}
I don't think so. As indicated in the concise answer by @Servy and the more detailed answer by @Luke Puplett, I believe that it is appropriate and indeed expected that this method should be named ConnectAsync
(because it returns an awaitable). In further support of this, @John Skeet in this answer to another question appends Async
to the method name regardless of the presence of the async
modifier.
Finally, on another question, consider this comment by @Damien_The_Unbeliever:
async/await
are implementation details of your methods. It matters not one jot whether your method is declaredasync Task Method()
or justTask Method()
, so far as your callers are concerned. (In fact, you are free to change between these two at a later point in time without it being considered a breaking change.)
From that, I infer that it is the asynchronous nature of the method that dictates how it should be named. The user of the method won't even know whether the async
modifier is used in its implementation (without the C# source code or CIL).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With