Потокобезопасный контекст базы данных потока данныхC#

Место общения программистов C#
Ответить
Anonymous
 Потокобезопасный контекст базы данных потока данных

Сообщение Anonymous »

Мое приложение получает несколько файлов и обрабатывает их в блоках потока данных. В одном из блоков UploadToDatabaseBlock я установил для MaxDegreeOfParalellism значение 8. Это создает несколько потоков, которые добавляют файлы в базу данных с помощью EntityFramework. Для контекста базы данных установлено значение «Область действия».
Поскольку он имеет область действия, я получаю исключение. Вторая операция началась в этом контексте до завершения предыдущей операции. Поскольку службы используют репозитории, которые используют один и тот же контекст базы данных для одного запроса API.
Проблема кажется универсальной: как использовать блоки потока данных (множественные потоки TPL) с EntityFramework и его DbContext. p>
Найденные мной решения:
  • Установите для DbContext значение Transient во внедрении зависимостей ASP .NET.
  • Создание экземпляра DbContext для каждого потока.

    ПЛЮС: Я читаю в Интернете, что это предпочтительный способ.

    Минусы :
    Во время загрузки я использую множество сервисов. Я вызываю частный метод, который вызывает другой метод, который вызывает разные классы сервисов и т. д.

    Мне удалось заставить его работать, создав статический класс AmbientScope и предоставив сервисы на уровне потока в каждом методе.
public void IsFileComplete() {
var serviceA = AmbientServiceScope.Current?.GetRequiredService();
var serviceB = AmbientServiceScope.Current?.GetRequiredService();
var serviceC = AmbientServiceScope.Current?.GetRequiredService();
var mediator = AmbientServiceScope.Current?.GetRequiredService();
if (serviceA is null || serviceB is null || ...)
{
throw new InvalidOperationException("No ambient scope available!");
}
// continue method logic
// public method because its used by other services/requests to check a file is complete,
// not only by UploadWithDataflow
}

Проблемы:

[*]Много шаблонного кода.
[*] Если метод используется из нескольких запросов API (Загрузка файлов, Проверка завершения файла), то запросы, которые не используют потоки, все равно должны создать Ambient Scope для работы.

Мне снова нужен шаблонный код и внедрить IServiceScopeFactory повсюду:

using var scope = serviceScopeFactory.CreateScope();
using (AmbientServiceScope.SetScope(scope.ServiceProvider))
{
...
}

Это распространенная проблема. Должно быть простое решение.
AmbientScope
public static class AmbientServiceScope
{
private static readonly AsyncLocal _currentScope = new();

public static IServiceProvider? Current => _currentScope.Value;

public static IDisposable SetScope(IServiceProvider serviceProvider)
{
var previous = _currentScope.Value;
_currentScope.Value = serviceProvider;

return new DisposeAction(() => _currentScope.Value = previous);
}

private class DisposeAction(Action disposeAction) : IDisposable
{
public void Dispose() => disposeAction();
}
}


Подробнее здесь: https://stackoverflow.com/questions/792 ... db-context
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»