. NET Core 3.1 BackgroundService - использование RabbitMQ и вставка с использованием EntityFrameCore - PullRequest
0 голосов
/ 28 апреля 2020

В настоящее время я пишу фоновый сервис, который читает сообщения из очереди и вставляет эти значения в базу данных ms sql. Я использую entityframecore для вставки значений в контекст.

Теперь у меня проблема с контекстом. Я получаю сообщение об ошибке:

InvalidOperationException: вторая операция началась в этом контексте, прежде чем предыдущая операция завершена. Любые члены экземпляра не гарантированно являются потокобезопасными. Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection ()

Теперь я знаю, что это проблема с asyn c, но все же ...

Я исправил это, определив новую область в начало. Но я не уверен, что это путь к go ... Вот мой код в настоящее время:

consumer.Received += async (ch, ea) =>
            {
                using (var scope = _scope.BeginLifetimeScope())
                {
                    var context = scope.Resolve<DatabaseContext>();
                    var content = Encoding.UTF8.GetString(ea.Body.ToArray());

                    var message = JsonConvert.DeserializeObject<RabbitMQMessageType>(content);

                    switch (message.Type)
                    {
                        case "config":
                            await HandleConfigMessage(message.Body, context);
                            break;
                        case "measurement":
                            await HandleMeasurementMessage(message.Body, context);
                            break;
                        case "log":
                            await HandleLogMessage(message.Body);
                            break;
                    }

                    _channel.BasicAck(ea.DeliveryTag, false);
                }
            };

Вы можете видеть, что я просто передаю контекст другим методам и .Add ( ) лица. Это путь к go?

Спасибо за помощь!

С уважением

1 Ответ

0 голосов
/ 29 апреля 2020

Entity Framework не поддерживает одновременную работу на одном DbContext. Если вы хотите использовать несколько потоков для связи с вашей базой данных, вам нужно создать несколько экземпляров DbContext. См. MSDN
Итак, короче говоря, DbContext не является потокобезопасным, поэтому предлагаемый способ регистрации вашего DbContext в вашем контейнере DI заключается в использовании Transient жизненный цикл:

services.AddDbContext<YourDbContext>(options =>  
  options.UseSqlServer(Configuration.GetConnectionString(Constants.YourConnectionString)),
  ServiceLifetime.Transient);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...