#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. Вы можете создавать/уничтожать несколько раз или создавать во внешнем методе и передавать его в другие методы.