.NET跨框架调用API出现DbContext多线程冲突问题求助
问题描述
我有两个分属不同解决方案的C#项目,一个基于.NET Core,另一个基于.NET Framework。需要从.NET Framework项目中调用.NET Core项目的API,调用代码如下:
response = await client.PostAsync(urlInterfacePrefix + "EmptyComponentAndSendToRefractory?ladle=" + h.Name + "&user=" + user + "§orPP=" + sectorPP + "&userPP=" + userPP + "&hostPP=" + hostPP , content);
其中urlInterfacePrefix变量存储API调用前缀。问题是首次调用方法正常,但后续调用抛出错误:
A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext.
.NET Core项目的Startup.cs中DbContext配置如下:
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<CoreDbContext>( options => options.UseSqlServer(Configuration.GetConnectionString("CoreConnection"), b => b.MigrationsAssembly("MOM.Core.WebAPI")).EnableSensitiveDataLogging()); IMapper mapper = MappingConfig.RegisterMaps().CreateMapper(); services.AddSingleton(mapper); services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); services.AddControllers(); AddSwagger(services); }
相关Repository构造代码:
private readonly CoreDbContext _db; private IMapper _mapper; protected ResponseDto _response; private HutOperation _hutOperation; public static List<OMM.Sector> _sectores = null; private Mutex mutex_process_message = new Mutex(); public TransferLadleRepository(CoreDbContext db, IMapper mapper) { _db = db; _mapper = mapper; _hutOperation = new HutOperation(db); _response = new ResponseDto(); }
解决方法
- 调整Repository的生命周期:如果
TransferLadleRepository被注册为Singleton,必须改成Scoped。因为AddDbContext默认是Scoped生命周期(每个请求对应一个实例),单例Repository会长期持有同一个DbContext,导致后续请求复用该实例引发多线程操作冲突。 - 通过依赖注入管理HutOperation:不要手动
new HutOperation(db),先为HutOperation定义接口(如IHutOperation),再将其注册为Scoped:
之后在services.AddScoped<IHutOperation, HutOperation>();TransferLadleRepository的构造函数中注入IHutOperation,替代手动实例化:
这样每个请求会获得独立的public TransferLadleRepository(CoreDbContext db, IMapper mapper, IHutOperation hutOperation) { _db = db; _mapper = mapper; _hutOperation = hutOperation; _response = new ResponseDto(); }HutOperation和对应DbContext,避免共享实例导致的并发问题。 - 确保异步操作全await:检查所有涉及DbContext的异步方法(包括
HutOperation内部的方法),必须用await等待操作完成,禁止使用.Result或.Wait()这类同步阻塞方式,否则会造成线程阻塞,引发DbContext复用冲突。 - 清理静态字段的DbContext依赖:静态字段
_sectores如果是通过DbContext查询填充的,要确保初始化过程线程安全,且不持有DbContext引用。可以用Lazy<T>实现线程安全的延迟初始化,避免直接关联DbContext。
内容的提问来源于stack exchange,提问作者Raulus
相关产品推荐
相关产品推荐

