ASP NET Core Использование асинхронного посредника с DbContext

Я пытаюсь получить доступ к dbContext через инъекцию зависимостей. И это работает.

Я добавляю dbcontext при запуске

Services.AddDbContextPool<ApplicationDbContext>(options =>
            {
                options.UseMySql(Configuration["ConnectionStrings:DefaultConnection"],
                    b => b.MigrationsAssembly("Persistence"));
                options.UseOpenIddict();
            });

Я также добавляю все обработчики запросов в Посредник

services.AddMediatR(typeof(ChangePasswordRequestHandler).GetTypeInfo().Assembly);

Я вызываю запрос внутри другого запроса в посреднике. Вот образец

    public class CreateComment : IRequestHandler<CreateCommentRequestModel, ResponseViewModel>
    {
        private readonly ApplicationDbContext _context;
        private readonly IMediator _mediator;
        public CreateComment(ApplicationDbContext context, IMediator mediator)
        {
            _context = context;
            _mediator = mediator;
        }

        public async Task<ResponseViewModel> Handle(CreateCommentRequestModel request, CancellationToken cancellationToken)
        {
            _ = _mediator.Send(new SendCommentNotificationRequestModel(), CancellationToken.None);
            return new ResponseViewModel();
        }

Вот еще один обработчик запросов

    public class SendCommentNotification : IRequestHandler<SendCommentNotificationRequestModel, ResponseViewModel>
    {
        private readonly ApplicationDbContext _context;
        private readonly IMediator _mediator;
        public SendCommentNotification(ApplicationDbContext context, IMediator mediator)
        {
            _context = context;
            _mediator = mediator;
        }

        public async Task<ResponseViewModel> Handle(SendCommentNotificationRequestModel request, CancellationToken cancellationToken)
        {
            await _mediator.Send(new SendNotificationToManyRequestModel(), CancellationToken.None);
            return new ResponseViewModel();
        }
    }

Вот мой третий обработчик

    public class SendNotificationToMany : IRequestHandler<SendNotificationToManyRequestModel, ResponseViewModel>
    {
        private readonly ApplicationDbContext _context;
        private readonly INotificationService _notificationService;
        public SendNotificationToMany(
            INotificationService notificationService, ApplicationDbContext context)
        {
            _notificationService = notificationService;
            _context = context;
        }

        public async Task<ResponseViewModel> Handle(SendNotificationToManyRequestModel request,
            CancellationToken cancellationToken)
        {
           //DbContext is disposed hence not usable when accessed here.

            return new ResponseViewModel();
        }
    }

Проблема в том, что DbContext удаляется при работе с третьим обработчиком. Что я могу сделать, чтобы решить эту проблему?

Если я добавлю await в первый обработчик, он будет работать как надо, но я не хочу ждать его, я хочу, чтобы он работал в фоновом режиме.

Я знаю, что исправление очень мало, но я не могу понять это.

Всего 2 ответа


Kestrel создает область обслуживания для срока действия запроса. По завершении области действия все службы IDisposable удаляются.

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

Или опубликуйте фоновое задание в фоновом сервисе, который откроет новую область для каждого запроса.


Я полагаю, ошибка находится здесь:

public async Task<ResponseViewModel> Handle(CreateCommentRequestModel request, CancellationToken cancellationToken)
{
    _ = _mediator.Send(new SendCommentNotificationRequestModel(), CancellationToken.None);
    return new ResponseViewModel();
}

Вам не хватает ключевого слова await , хотя вы вызываете асинхронный метод.

Поэтому добавьте его в _ = await _mediator.Send(new SendCommentNotificationRequestModel(), CancellationToken.None); и ты должен быть золотым


Есть идеи?

10000