【问题标题】:EF and Multiple Instances of IHostedServiceEF 和 IHostedService 的多个实例
【发布时间】:2021-03-11 04:18:54
【问题描述】:

我的 DI 容器中注册了多个 IHostedService (BackgroundService) 实例。

services.AddHostedService<ResourceMatchingMessageListeningService>();
services.AddHostedService<ResourceMatchingMessageListeningService2>();
services.AddHostedService<ResourceMatchingMessageListeningService3>();
services.AddHostedService<ResourceMatchingMessageListeningService4>();
services.AddHostedService<ResourceMatchingMessageListeningService5>();

每个服务都侦听不同的 Azure 服务总线队列。收到消息时,它会通过 EF Core 写入数据库。如果我运行一个服务,它工作正常,只要我运行 2 个或更多,我就会收到错误:

在前一个操作之前在此上下文上启动了第二个操作 完全的。这通常是由于不同的线程使用相同的 DbContext 的实例。

我假设出现此错误是因为 EF Core 不是线程安全的,并且托管服务都在不同的线程中运行。

我厌倦了通过将 EF 的服务生命周期设置为瞬态来解决此问题),但我仍然遇到同样的错误。

services.AddDbContext<MyDataContext>(options => 
            options.UseSqlServer(connectionString, sqlServerOptions => 
            sqlServerOptions.CommandTimeout(120)),
            ServiceLifetime.Transient, ServiceLifetime.Transient);

对这里的潜在解决方案有什么建议吗?

【问题讨论】:

  • 你试过作用域吗?

标签: c# asp.net azure entity-framework azureservicebus


【解决方案1】:

您需要为每个托管服务创建一个新的服务范围,然后从该范围请求您的 DbContext。

using var scope = services.CreateScope();
var context = scope.ServiceProvider.GetService<MyDataContext>();

您可能希望为您处理的每条消息创建一个服务范围。甚至可能是一个单独的作用域服务来处理每条消息。

不幸的是,该实现开始看起来像服务定位器反模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    相关资源
    最近更新 更多