Найти в Дзене

Запуск длительных задач с помощью Task.Run


Если вы планируете запускать длительные задачи с помощью Task.Run и внутри создавать "scope" для получения сервисов из контейнера служб в ASP.NET, то нельзя использовать IServiceProvider для этого, тк он регистрируется как Scoped и внутри Task.Run может выйти ошибка, что используемый объект уже задиспоузился.

Поэтому используем IServiceScopeFactory - данный интерфейс регистрируется как Singleton.

Task.Run(async () =>
{
  using (var scope = _serviceScopeFactory.CreateScope())
  {
   var myService = scope.ServiceProvider.GetRequiredService<IMyService>();
   await myService .Work();
  }
});

Чтобы логировать ошибки из Task.Run нужно добавить обработчик события TaskScheduler.UnobservedTaskException (в Program перед сборкой хоста):
TaskScheduler.UnobservedTaskException += OnTaskSchedulerOnUnobservedTaskException;
Около минуты