关于多线程efcore dbcontext 的解决方案。
- 首先我们大部分的efcore框架用的DbContext(或者封装的repo)都是底层注入的上下文容器实体。
- 然后Dbcontext不是线程安全的,也就是说,你在当前线程中,只能创建一个 DbContext 实例对象(特定情况下),并且这个对象并不能被共享。
- 当我们使用多线程去执行数据库的操作时就有可能造成各种问题。
- 我这里就在网站启动时去跑发布和订阅任务。
- 解决方案:使用using从ioc容器中创建新的dbcontext 。然后用完立即释放。这样就不会占用主线程的dbContext了。
/// <summary> /// 执行未发布成功的信息 /// </summary> public void ToBePublishs() { Console.WriteLine("开始执行未发布任务"); using (var _eventClientDbContext = (EventClientDbContext)ServiceProvider.CreateScope().ServiceProvider.GetService(typeof(EventClientDbContext))) { var PublishsList = _eventClientDbContext.Publishs.Where(a => a.PublishStatus == false).ToList(); List<Publishs> publishsList = PublishsList.ToList(); if (publishsList.Count > 0) { Console.WriteLine("开始执行未发布任务,本次任务执行条数为:" + publishsList.Count()); using (var tran = _eventClientDbContext.Database.BeginTransaction()) { foreach (var PublishsInfo in publishsList) { //var Result = ClientPost(ClientType.Publishs, PublishsInfo); var Result = string.Empty; try { Result = ClientPost(ClientType.Publishs, PublishsInfo); if (Result.Contains("Success")) { PublishsInfo.PublishStatus = true; PublishsInfo.ModifyTime = DateTime.Now; _eventClientDbContext.Publishs.Update(PublishsInfo); _eventClientDbContext.SaveChanges(); } } catch (Exception ex) { Console.WriteLine("执行未发布成功的信息抛出异常:" + ex.StackTrace + ex.Message); continue; } } tran.Commit(); } } } Console.WriteLine("未发布任务End"); }
stay hungry stay foolish!