At the end of an async method, should I return or await?

You can't return the task if the method itself is declared to be async - so this won't work, for example:

async Task BarAsync()
{
    return BazAsync(); // Invalid!
}

That would require a return type of Task<Task>.

If your method is just doing a small amount of work and then calling just one async method, then your first option is fine, and means there's one fewer task involved. You should be aware that any exceptions thrown within your synchronous method will be delivered synchronously though - indeed, this is how I prefer to handle argument validation.

It's also a common pattern for implementing overloading e.g. by cancellation token.

Just be aware that if you need to change to await something else, you'll need to make it an async method instead. For example:

// Version 1:
Task BarAsync()
{
    // No need to gronkle yet...
    return BazAsync();
}

// Oops, for version 2 I need to do some more work...
async Task BarAsync()
{
    int gronkle = await GronkleAsync();
    // Do something with gronkle

    // Now we have to await BazAsync as we're now in an async method
    await BazAsync();
}

Check out this link where it is described: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx

async Task<int> TaskOfTResult_MethodAsync()
{
    int hours;
    // . . .
    // The body of the method should contain one or more await expressions.

    // Return statement specifies an integer result.
    return hours;
}

    // Calls to TaskOfTResult_MethodAsync from another async method.
private async void CallTaskTButton_Click(object sender, RoutedEventArgs e)
{
    Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync();
    int intResult = await returnedTaskTResult;
    // or, in a single statement
    //int intResult = await TaskOfTResult_MethodAsync();
}






// Signature specifies Task
async Task Task_MethodAsync()
{
    // . . .
    // The body of the method should contain one or more await expressions.

    // The method has no return statement.  
}

    // Calls to Task_MethodAsync from another async method.
private async void CallTaskButton_Click(object sender, RoutedEventArgs e)
{
    Task returnedTask = Task_MethodAsync();
    await returnedTask;
    // or, in a single statement
    //await Task_MethodAsync();
}