1

我没有找到类似的问题/答案来达到我的目的。MVC 4/EF中的数据库上下文和异步函数5

在我的控制器(MVC 4/EF 5应用程序)的少量动作中,我有更新数据库的功能,但这些功能不会影响用户输出(选择后更新信息的功能)。我想用异步线程发送这些函数(这将在用户获得渲染页面后完成)。我不想等待线程完成和呈现页面。 在这种情况下数据库的上下文呢? 我的情况下寿命为“每个请求”,并在Application_EndRequest删除:

protected virtual void Application_EndRequest() 
{ 
    var entityContext = HttpContext.Current.Items["_Context"] as DbContext; 
    if (entityContext != null) 
     entityContext.Dispose(); 
} 

我用自己的线程上下文(使用块正确处置)。

using (DbContext db = new DbContext()) 
{ 
    .... 
} 

但如果我要附加实体的DbContext在线程我得到一个错误,在一些情况下“与已经在ObjectStateManager存在相同键的对象”。这很奇怪,因为我在使用AsNoTracking()选项加载并且实体状态在调用新线程之前在主Context中“分离”。 在其他情况下,当我在线程中再次尝试从数据库请求实体并修改它(而不是附加)时,出现错误“对象处于分离状态”多次 上下文的两个实例使用一个ObjectStateManager?并且错误依赖于主线程上下文处理的时间而出现。我的意思是在处理主要上下文之前或之后,我在线程中使用上下文...

如何在这种情况下使用具有自己的上下文的异步线程? 谢谢。

回答

0

我找到了答案和所有作品。 Start a long time background task。 您可以传递Task StartNew()方法的一个参数,该参数指示您正在启动的任务是“长时间运行”,这提供了任务计划程序在新线程上启动任务的提示。

var task = Task.Factory.StartNew(Stuff, TaskCreationOptions.LongRunning); 

感谢,medkg15

2

你有几个问题在这里:

1)如果你把一个对象,或者它的导航性能,属于一个上下文,并尝试在其他情况下使用它们,你会得到你有错误看到。

2)只要您的请求完成后,IIS是免费回收AppDomain.当发生这种情况时,您的工作线程将与极端predjudice被中止。这意味着你不能依赖工作线程去做任何事情。

如果您想推迟一些昂贵的工作,您应该将工作传递给在另一个进程中实现的某种消息队列 - 很可能是Windows服务。

+0

我不知道1)。我用AsNoTracking()编写了急切的加载。实体与上下文分离...还有导航属性。 关于2) - 可能... 谢谢。 – 2013-03-23 18:10:39