Исключение Nullreference не отображается, когда asyn c Задача отброшена - PullRequest
0 голосов
/ 27 января 2020

У меня есть asyn c Задача с сигнатурой метода, определенной следующим образом:

public async Task<bool> HandleFooAsync()

При выполнении этой задачи asyn c и отбрасывании результатов, исключения, возникающие в этой задаче, делают не отображаются в наших журналах.

_ = _slackResponseService.HandleFooAsync();

Когда я жду выполнения задания, я вижу ошибку в наших журналах

var result = await _slackResponseService.HandleFooAsync();

Это ожидаемое поведение? Есть ли способ найти решение между: «не ждите результата, но, тем не менее, регистрируйте ошибки ...»? Мы потратили часы на отладку наших настроек журналирования, просто чтобы убедиться, что наши настройки логирования верны, но discard означает в do tnet, что все отбрасывается, даже журналы. Это довольно новая для нас перспектива, исходящая из Python фона.

Наши настройки ведения журнала соответствуют настройкам ведения журнала по умолчанию для do tnet core 3 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.1

Ответы [ 3 ]

3 голосов
/ 27 января 2020

Да, это ожидаемое поведение. Звонок таким образом может рассматриваться как анти-паттерн. Вы можете прочитать об этом C# Asyn c Antipatterns

Вам нужно что-то, что называется "Огонь и забудь". Одну из его реализаций можно найти в репозитории AsyncAwaitBestPractices (также доступен nuget).

0 голосов
/ 28 января 2020

Одним из решений является подписка на событие TaskScheduler.UnobservedTaskException. Это не идеально, потому что событие возникает, когда сбойный Task является сборщиком мусора, что может произойти спустя много времени после фактического сбоя.

Другим решением может быть использование метода расширения при каждом запуске задачи и забыли. Вот так:

_slackResponseService.HandleFooAsync().FireAndForget();

Вот базовая c реализация метода FireAndForget:

public async static void FireAndForget(this Task task)
{
    try
    {
        await task;
    }
    catch (Exception ex)
    {
        // log the exception here
    }
}
0 голосов
/ 28 января 2020

Задание в. net и netcore ожидаются. Если он не ожидается, область может быть уничтожена до завершения метода asyn c.

Если вы хотите запускать задачи в фоновом режиме и не ждать результата, вы можете использовать BackgroundService в .netcore или третья сторона, такая как Hangfire, которая поддерживает работу с огнем и забыванием из коробки

https://medium.com/@daniel.sagita / backgroundservice-for-a-long-running-work-3debe8f8d25b https://www.hangfire.io/

...