Methods that perform asynchronous operations don't need to use await
if:
Consider this method that returns a Task
:
public async Task<User> GetUserAsync(int id)
{
var lookupKey = "Users" + id;
return await dataStore.GetByKeyAsync(lookupKey);
}
If GetByKeyAsync
has the same signature as GetUserAsync
(returning a Task<User>
), the method can be simplified:
public Task<User> GetUserAsync(int id)
{
var lookupKey = "Users" + id;
return dataStore.GetByKeyAsync(lookupKey);
}
In this case, the method doesn't need to be marked async
, even though it's preforming an asynchronous operation. The Task returned by GetByKeyAsync
is passed directly to the calling method, where it will be await
ed.
Important: Returning the Task
instead of awaiting it, changes the exception behavior of the method, as it won't throw the exception inside the method which starts the task but in the method which awaits it.
public Task SaveAsync()
{
try {
return dataStore.SaveChangesAsync();
}
catch(Exception ex)
{
// this will never be called
logger.LogException(ex);
}
}
// Some other code calling SaveAsync()
// If exception happens, it will be thrown here, not inside SaveAsync()
await SaveAsync();
This will improve performance as it will save the compiler the generation of an extra async state machine.