在此上下文中启动了第二个操作
Posted
技术标签:
【中文标题】在此上下文中启动了第二个操作【英文标题】:A second operation started on this context 【发布时间】:2019-04-07 21:32:17 【问题描述】:在我的控制器中,我在保存到 DB 的日期之后执行另一个 Void 函数。但有时它会显示此错误:
第二个操作在前一个上下文之前开始 异步操作完成。使用“等待”确保任何 异步操作在调用另一个方法之前已经完成 在这种情况下。不保证任何实例成员都是线程 安全。
...这是我的控制器的示例:
public ActionResult All(Chapter chapter)
var x = db.Post.Where(p => p.PostID == chapter.PostID).FirstOrDefault();
if (x == null)return View(chapter);
counter++;
db.Chapter.Add(chapter);
db.SaveChangesAsync();
savepost(chapter.PostID, counter);
return RedirectToAction("Index");
这里是 Void 方法:
public void savepost(int id,int counter)
var article = db.Post.Find(id);
article.LastUpdate = DateTime.Now;
article.ChapterCount = counter;
db.Entry(article).State = EntityState.Modified;
db.SaveChanges();
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:最短修复:
//db.SaveChangesAsync();
db.SaveChanges();
稍微好一点的选择:
public async Task<ActionResult> All(Chapter chapter)
....
await db.SaveChangesAsync();
...
您没有等待对 SaveChangesAsync() 的调用,这意味着它将(可以)在单独的线程上分叉。然后它给你这个错误,一个 DbContext 不能在线程之间共享。
作为练习,您可以对 SavePost() 方法进行类似的更改:
使其成为async Task
方法
将 SaveChanges() 替换为 await db.SaveChangesAsync()
等待 SavePost() 的调用
【讨论】:
遇到这个问题 'ChapterID' 属性是对象关键信息的一部分,不能修改。 完全不相关,再问一个问题 - 并在那里提供相关代码。 作为一种解决方案,它可以工作,但是在我的控制器中,我使用 foreach 将多个模型添加到数据库中,因为 Chapter 的表 id 是标识并且由模型给出,所以我遇到了这个问题.. 你知道我是怎么做到的吗?可以为每个模型添加多模型,因为它是主键,所以重要的是在 DB 中获取下一个 Id 好吧,在我离开了我发布的操作结果之后,我建议你将 void 更改为异步任务,并将 db.save 更改为 SaveChangesAsync 它的工作原理,没问题..谢谢所有人都做得很好 当你使 SavePost 异步时,你必须等待它,你不能用你原来的非任务 All 动作来做到这一点......以上是关于在此上下文中启动了第二个操作的主要内容,如果未能解决你的问题,请参考以下文章
UserManager 错误“在前一个操作完成之前在此上下文上启动了第二个操作”
UserManager 错误 - 在前一个异步操作完成之前在此上下文上启动了第二个操作
asp.net core 在前一个操作完成之前在此上下文上启动了第二个操作
EF 错误:在前一个异步操作完成之前在此上下文上启动了第二个操作