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 awaited.

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.