我最近偶然发现了一个事实,即我无法在单独的线程中使用相同的DBContext实例。我有两个共享相同DBContext的服务,所以最终出现异常
System.InvalidOperationException:'在上一个操作完成之前,第二个操作在此上下文上开始。这通常是由使用相同DbContext实例的不同线程引起的。有关如何避免DbContext线程问题的更多信息,请参见https://go.microsoft.com/fwlink/?linkid=2097913。
所以我的代码主要是由ASP.Net核心向导生成的
// program.cs
private static void ConfigureServices(string settings, IServiceCollection services)
{
services.AddDbContext<MMCC.Terminal.Service.Data.TerminalDbContext>((provider, options) =>
{ options.UseNpgsql(configuration.GetConnectionString(nameof(TerminalDbContext)));
});
}
public MyService1(TerminalDbContext dbTerminal)
{
_dbTerminal = dbTerminal;
}
public MyService2(TerminalDbContext dbTerminal)
{
_dbTerminal = dbTerminal;
}
用法
void Run()
{
_hourTimer = new Timer(UpdateOnceInHour, null, 0, 60 * 60 * 1000);
_minuteTimer = new Timer(UpdateEveryMinute, null, 0, 1 * 60 * 1000);
}
private async void UpdateOnceInHour(object state)
{
_mService1.DoSomething()
}
private async void UpdateOnceInHour(object state)
{
_mService2.DoSomething()
}
所以这是我有例外的时候。
// Service 1
// thread 1
private DoSomething()
{
await _dbTerminal.SomeTable1.ToListAsync();
}
// Service 2
// thread 2
private DoSomething()
{
await _dbTerminal.SomeTable2.ToListAsync();
}
我试图弄清楚如何解决这个问题。有什么标准图案吗?我尝试重构代码,而不是将TerminalDbContext注入Service1,Service2中,而是注入IServiceProvider,然后对TerminalDbContext做GetService,但看来我最终还是使用相同的DBContext实例。
您应该能够在需要唯一实例的任何地方使用using语句,并实例化一个新的上下文,该上下文将在完成后被处置。
using (var newContext = new TerminalDbContext(new DbContextOptionsBuilder<TerminalDbContext>()
{
// Define options
}))
{
DoSomething();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句