5

我遇到了存储在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() 应该只有当一切都完成时才被调用,不是吗?

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

谢谢!

4

2 回答 2

1

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

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

于 2012-06-13T17:56:02.643 回答
1

假设您有一个为您提供当前 ObjectContext 的类,那么程序员可能会根据博客或类似内容中的一些示例编写以下代码:

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

并在请求结束之前处理了 ObjectContext。

如果你想测试 ObjectContext 被放置在哪里,你可以这样做:

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

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

public void ActuallyDisposePlease() {
    base.Dispose();
}

并在 Application_EndRequest 中调用ActuallyDisposePlease() 方法。

当然,这是为了测试/调试/诊断的角度,永远不要影响生产。

于 2012-06-13T18:08:41.443 回答