Когда мой .NET-код возвратил задачу, он не дал ожидаемого результата.Изменив его на async / await, исправил.Зачем? - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть довольно стандартный код для типичного .NET Core 2+ program.cs.В основном я настраиваю ведение журнала.

С приведенным ниже кодом это не async/await, и происходит следующее:

  • Регистрация происходит во время процесса запуска 100%.
  • CloseAndFlush(); происходит почти мгновенно, до того, как все остальное приложение выполняет.
  • В каких-либо контроллерах не ведется регистрация.

Отчасти это связано с тем, как Serilogработает, но это не очень важный бит, AFAIK.

Код переходит прямо на return CreateWebHostBuilder(args).Build().RunAsync(); .. когда я подумал, что это та часть, где он будет awaited вызывающим?Когда я отлаживаю свое приложение, оно ожидает (зависает) в этой строке ... пока приложение не завершит завершение .Как только он готов принимать соединения, он возвращается сюда ... и проходит через ... что означает, что он вызывает Log.CloseAndFlush(), а затем return Task.CompletedTask.

Код ошибки:

public static Task Main(string[] args)
{
    Log.Logger = new LoggerConfiguration()....CreateLogger();

    try
    {
        // awaits here until the app has 100% started, then continues.
        return CreateWebHostBuilder(args).Build().RunAsync();
    }
    catch (Exception exception)
    {
        Log.Logger.Fatal(exception, "Host terminated unexpectantly. Sadness :~(");
    }
    finally
    {
        // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
        Log.CloseAndFlush();
    }

    return Task.CompletedTask;
}

Теперь изменив это на async/await, все исправляется.Код правильно ожидает на return CreateWebHostBuilder(args).Build().RunAsync(); .. и затем CloseAndFlush() вызывается, когда приложение закрывается / завершается.

    public static async Task Main<T>(string[] args) where T : class
    {
        Log.Logger = new LoggerConfiguration()....CreateLogger();

        try
        {
            // Correctly waits here until the app explodes or ctrl-c has been pressed.
            await CreateWebHostBuilder<T>(args).Build().RunAsync();
        }
        catch (Exception exception)
        {
            Log.Error(exception, "Stopped program because of an exception.");
        }

        Log.Debug("Finished shutting down app.");

        // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
        Log.CloseAndFlush();
    }

Возврат задачи, вероятно, будет только подходящимесли метод только делает one async/await в нем И это последнее в методе?

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Возвращая Task 1 вместо await, это ваш способ сказать: "* этот метод не может сделать здесь" 2 .

Если это не так (как здесь, где вы еще не хотите, чтобы ваш пункт finally выполнялся), вы еще не закончили.Вам нужен какой-то способ запуска некоторого кода в более поздний момент времени, но у вас нет ничего полезного, чтобы сделать сейчас .И это именно то, что await позволяет вам сигнализировать.


1 Как Джонас упоминает , это точно верно и для не Task возвратов тоже.

2 Я игнорирую случай, когда вы берете Task из другого места, добавляете ContinueWith и возвращаете полученное Task, потому что там вы используетедругой механизм, гарантирующий, что вы сможете запустить код позже, и это не точно «этот метод», который выполняется в продолжении.

0 голосов
/ 23 ноября 2018

Будет ли возвращение Задачи, вероятно, подходящим, только если метод выполняет в нем только одну асинхронную / ожидающую работу И это последнее в методе?

По сути, да.Возврат задачи, как в вашем первом фрагменте, позволит блоку finally работать, когда вы покидаете область действия, так же, как и любой другой оператор возврата внутри попытки с ассоциированным оператором finally.И, как прокомментировал ckuri, ваш блок catch не будет делать то, что вы хотите, так как он не будет перехватывать исключения из задачи, только из самой установки CreateWebHostBuilder.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...