gpt4 book ai didi

c# - 多线程 API 应用程序中的 EF 核心 DbContext

转载 作者:行者123 更新时间:2023-11-30 15:14:10 25 4
gpt4 key购买 nike

tl;dr How can I use Entity Framework in a multithreaded .NET Core API application even though DbContext is not threadsafe?

上下文

我正在开发一个 .NET Core API 应用程序,它公开了几个访问数据库并从中读取数据的 RESTful 接口(interface),同时运行多个 TimedHostedServices 作为后台工作线程,定期从其他网络服务轮询数据并将它们存储到数据库。

我知道 DbContext 不是线程安全的。我在 Stackoverflow 上阅读了很多文档、博客文章和答案,我可以找到很多(部分矛盾的)答案,但在使用 DI 时没有真正的“最佳实践”。

我尝试过的事情

使用默认 ServiceLifetime.Scoped通过 AddDbContext扩展方法由于竞争条件导致异常。

我不想使用锁(例如信号量),因为明显的缺点是:

  • 代码被锁污染,try/catch/finally 安全释放锁
  • 它看起来并不“稳健”,即当我忘记锁定访问 DbContext 的区域时。
  • 在处理同时处理并发连接和访问的数据库时,在应用程序中人为地同步数据库访问似乎是多余的和“不自然的”

不注入(inject) MyDbContext但是DbContextOptions<MyDbContext>相反,仅在我需要访问数据库时使用 using 构建上下文在读/写之后立即处理它的语句似乎有很多资源使用开销和不必要的许多连接打开/关闭。

问题

我很纳闷:这怎么能实现呢?

我不认为我的用例非常特别——从后台工作人员填充数据库并从 Web API 层查询它——所以应该有一种有意义的方法来使用 ef 核心来完成这项工作。

非常感谢!

最佳答案

只要您的 TimedHostedServices 触发,您就应该创建一个范围。

在构造函数中注入(inject)服务提供者:

public MyServiceService(IServiceProvider services)
{
_services = services;
}

然后在任务触发时创建一个作用域

using (var scope = _services.CreateScope())
{
var anotherService = scope.ServiceProvider.GetRequiredService<AnotherService>();

anotherService.Something();
}

可以使用更完整的示例 in the doc

关于c# - 多线程 API 应用程序中的 EF 核心 DbContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55777022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com