在application_endrequest上释放对象上下文

本文关键字:释放 对象 上下文 endrequest application | 更新日期: 2023-09-27 18:36:30

我遇到了存储在 HttpContext.Current.Items 中的 EF4 对象上下文的问题,然后希望在请求完全处理后立即释放。

Aplication_EndRequest事件中,我调用 RepositoryContext 的 Terminate() 方法,该方法将从 HttpContext.Current.Items 集合中找到活动的 ObjectContext,并在其连接上调用 Close(),在其连接上调用 Dispose()。

问题是有时我会在我的一个页面上遇到奇怪的行为。在某些情况下,我收到错误说:

ObjectContext 实例已被释放,不能再用于需要连接的操作

我想这可能会发生,因为不仅页面请求在完成后调用Application_EndRequest事件,而且图像请求等也调用,因此有时其他请求可能会在完成其工作之前处理主页请求 ObjectContext,但这不应该发生,因为一切都是在集合 HttpContext.Current.Items 上进行的,当然不会在 HTTP 请求之间共享。

此外,从研究中可能是由于某些数据库请求的延迟加载引起的,但这里不应该是这种情况,因为我不会在代码的其他任何地方调用 Dispose(我已经检查过),因此只有在一切都完成后才应该调用 EndRequest 上的 Dispose(),不是吗?

关于可能导致这种情况的任何想法?如何测试?你有什么建议?

谢谢!

在application_endrequest上释放对象上下文

这意味着Dispose()已经在ObjectContext上被调用了。关于为什么会发生这种情况有许多不同的原因,但归结为在Application_EndRequest之前调用Dispose()的事实。如果没有所有的来源,就不可能确切地说出原因。

因为你在寻求建议,我的第一个建议是将ObjectContext从HttpContext中移除。数据库连接应仅存在很短的时间,并执行特定任务。如果它是短暂的,你可以将 ObjectContext 放在 using 语句中,该语句将自动为您调用 Dispose()。

假设你有一个为你提供当前 ObjectContext 的类,程序员可能按照博客或类似内容中的一些示例编写了以下内容:

using(var context = ContextProvider.GetCurrentContext()){
    ...
}

并在请求结束之前释放了对象上下文。

如果要测试ObjectContext的释放位置,可以执行以下操作:

在 ObjectContext 实现中,将 Dispose 方法更改为:

public override void Dispose() {
    throw new InvalidOpearationException("Gotcha!");
}
public void ActuallyDisposePlease() {
    base.Dispose();
}

并在Application_EndRequest调用 ActuallyDisposePlease() 方法。

当然,这是为了测试/调试/诊断的角度,永远不应该进入生产环境。