Запретить удаление DbContext до завершения асинхронной задачи

#entity-framework #asp.net-core #asynchronous #dbcontext

Вопрос:

У меня есть контроллер веб-API C# core (реализация Microsoft.AspNetCore.Mvc.ControllerBase), который имеет метод API A и метод API B. A является асинхронным и запускает и забывает асинхронный рабочий поток. B синхронно.

И A (и его рабочий поток), и B читают и записывают из одной и той же базы данных с помощью entity framework. Но проблема, с которой я сталкиваюсь, заключается в том, что объект DbContext удаляется до завершения рабочего потока A.

Я знаю о принципе, согласно которому владелец одноразового объекта должен как создавать, так и распоряжаться им. Так я считал упаковка в DbContext, который в репозитории класс, который не одноразовые, но это, кажется, нарушает правила анализатора: «CA1001: типы, одноразовым поля должны быть одноразовыми» — https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1001 но если я создаю объект репозитория одноразовые, dotnet ограничителя ядра распоряжается он, когда вернется (но до ее рабочий поток завершается).

Я также рассматривал возможность создания одноэлементного репозитория, но это нарушает принцип, согласно которому объекты DbContext должны быть недолговечными.

Цените любые предложения, которые у вас могут быть!

Комментарии:

1. будет ли использование размещенной службы вариантом? Затем размещенная служба может иметь свой собственный экземпляр DbContext?

2. @MaartenDev это полезное предложение, но из того, что я читаю, размещенные службы работают в течение всего срока службы сервера, и, по-видимому, объекты DbContext должны быть недолговечными. Конечно, у меня могла бы быть размещенная служба, которая отвечала бы за запуск рабочих потоков, но затем я думаю, что это возвращает меня в исходное положение. Пожалуйста, поправьте меня, если я неправильно понял ваше предложение.

Ответ №1:

A является асинхронным и запускает и забывает асинхронный рабочий поток.

Тогда рабочий поток не должен использовать область DbContext, управляемую внедрением зависимостей. Вместо этого он должен создать экземпляр DbContext в using блоке и явно управлять его временем жизни в коде.

Комментарии:

1. @david-browne-microsoft, но, как я уже упоминал, VS затем настаивает на том, чтобы я пометил работника как одноразового, и в этом случае сам работник удаляется, когда возвращается метод A (до того, как работник закончил свою работу).

2. Я предполагал, что DbContext должен быть локальной переменной, объявленной в using блоке, а не членом какого-либо другого одноразового типа.

3. @DavidBrowne-Microsoft В порядке, имеет смысл иметь DbContext в блоке using, но, учитывая, что рабочий поток использует его несколькими методами, разве он не должен быть создан один раз в конструкторе и использоваться как переменная уровня класса? И если да, то не возвращает ли это меня к началу с тем же возражением анализатора?

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