![](/img/trans.png)
[英]Is there a way to manually start BackgroundService in Asp.Net core 3.1
[英].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.