簡體   English   中英

.NET Core 3.1 BackgroundService - 使用 RabbitMQ 並使用 EntityFrameCore 插入

[英].NET Core 3.1 BackgroundService - Consume RabbitMQ and insert using EntityFrameCore

我目前正在編寫一個后台服務,它從隊列中讀取消息並將這些值插入到 mssql 數據庫中。 我正在使用 entityframecore 將值插入到上下文中。

現在我遇到了上下文問題。 我不斷收到錯誤:

InvalidOperationException:在前一個操作完成之前在此上下文上啟動了第二個操作。 不保證任何實例成員都是線程安全的。 Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()

現在我知道這是異步的問題,但仍然......

我通過在開始時定義一個新的 scope 來解決這個問題。 但我不確定這是否是通往 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 的路嗎?

謝謝您的幫助!

親切的問候

實體框架不支持對單個DbContext進行並發操作。 如果要使用多個線程與數據庫通信,則必須創建多個 DbContext 實例。 見 MSDN
因此,簡而言之,DbContext 不是線程安全的,這就是為什么在 DI 容器中注冊 DbContext 的建議方法是使用Transient生命周期:

services.AddDbContext<YourDbContext>(options =>  
  options.UseSqlServer(Configuration.GetConnectionString(Constants.YourConnectionString)),
  ServiceLifetime.Transient);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM