"async Task" ждет "Task" vs "Task then return task"

Быстрый вопрос..

Чтобы получить четкое базовое понимание асинхронного программирования и await, я хотел бы знать, в чем разница между этими двумя фрагментами кода, когда речь идет о многопоточности и последовательности выполнения и времени:

Это

public Task CloseApp()
{
        return Task.Run(
                         ()=>{ 
                                // save database
                                // turn off some lights
                                // shutdown application
                          });
}

В сравнении с этим:

public async Task CloseApp()
{
        await Task.Run(
                         ()=>{ 
                                // save database
                                // turn off some lights
                                // shutdown application
                          });
}

если я вызываю его в этой процедуре:

private async void closeButtonTask()
{
    // Some Task 1
    // ..

    await CloseApp();

    // Some Task 2
    // ..
}

Ответ 1

Это почти то же самое (с точки зрения потоков и т.д.). Но для второго (используя await) компилятор будет создавать больше дополнительных ресурсов.

Способы, объявленные как async и использующие await, преобразуются компилятором в конечный автомат. Поэтому, когда вы нажмете await, поток управления возвращается вызывающему методу, и выполнение вашего метода async возобновляется после await, когда ожидаемый Task завершен.

Поскольку после вашего await больше нет кода, нет необходимости использовать await. Просто верните Task достаточно.

Ответ 2

Между этими подходами очень мало различий. По сути, они имеют одну и ту же семантику. Однако версия с async/await завершает выполнение внутренней задачи во внешней сгенерированной компилятором задаче. Версия, отличная от асинхронной, не поддерживает. Таким образом, неасинхронная версия (очень незначительно) более эффективна.