Почему AsyncContext необходим при использовании async/wait с консольным приложением?

Я вызываю метод async в своем консольном приложении. Я не хочу, чтобы приложение закрывалось вскоре после его запуска, то есть до того, как все задачи будут завершены. Кажется, я могу это сделать:

internal static void Main(string[] args)
{
    try
    {
        Task.WaitAll(DoThisAsync());
    }
    catch (Exception ex)
    {
        Console.Error.WriteLine(ex);
        throw;
    }
}

internal static async Task DoThisAsync()
{
    //...
}

Но согласно статье Стивена Клири кажется, что я не могу этого сделать и вместо этого должен создать какой-то контекст для асинхронного возвращения когда это делается (например, AsyncContext).

Приведенный выше код работает, и он возвращается в основной поток после Task.WaitAll(DoThisAsync());, поэтому зачем мне использовать пользовательский контекст?

Ответ 1

Это не требуется; это только мои предпочтения.

Вы можете синхронно блокировать задачу в Main (используя Wait/Result/WaitAll). Семантика немного отличается; в частности, если асинхронный код выходит из строя, тогда Wait/Result/WaitAll будет обертывать исключение в AggregateException, а AsyncContext - нет.

Кроме того, AsyncContext особенно относится к основной теме; вместо отправки продолжений в пул потоков, он отправит их обратно в этот основной поток (по умолчанию, вы всегда можете использовать ConfigureAwait(false), чтобы этого избежать). Я считаю это полезным, если я пишу консольное приложение "доказательство концепции", потому что AsyncContext ведет себя очень похоже на контексты пользовательского интерфейса.

Но в конце дня это просто вопрос предпочтения.