我的对象被处理在哪里?

3
我遇到一个奇怪的问题:我在一个 .aspx 页面中使用了 SPContext.Current.Web,但最终出现了“尝试使用已关闭或已释放且不再有效的 SPWeb 对象”错误消息。

根据我的观察,SPContext.Current.Web 已被某个人处置,但我不知道是在哪里处理的。我只想知道:通过 Visual Studio 2005 的调试器,我能否以某种方式查看谁或在哪里处理了一个对象?由于我既没有创建也没有源代码,设置断点是一个问题。
找出谁处理给定对象的方法,并在不随意注释行的情况下进行处理,是什么好方法?
(注意:该问题已经解决,但问题本身也适用于 Sharepoint 之外的情况。)

我解决了实际问题(我确实在完全不同的位置意外地处理了一个对象),但由于我通过注释掉一些东西并且只是“猜测”来解决它,所以我将问题留给其他人,因为这可能对他们有趣。 - Michael Stum
你可能想把那个评论发表为一个实际的答案... - John Rudy
我同意John的观点 - 在看到他的评论之前,我已经读了几遍这篇文章,这也解决了我的问题 :) - Andy Mikula
3个回答

6

请按照以下步骤检查是否有帮助:

  1. 使用调试(Debug) > 新建断点(New Breakpoint) > 在函数处中断(Break at Function... (Ctrl+B))添加新断点。
  2. 在“函数”编辑框中输入Microsoft.SharePoint.SPWeb.Dispose
  3. 忽略对话框,该对话框指出Intellisense无法找到指定位置。
  4. 在调试器下运行。
  5. 当断点被命中时,您可以在调用堆栈上看到谁调用了Dispose方法。希望在某些时候命中断点时,一个堆栈帧在您的源代码中。

如果在命中断点时出现对话框,提示当前位置没有可用的源代码,请关闭它。


注意:因为我没有安装SharePoint,所以我用System.IO.StreamReader.Dispose进行了测试,但我猜SPContext.Current.Web也应该可以工作。请在评论中告诉我们。


我会尽快检查,但那看起来像是可行的东西。 - Michael Stum
好的,测试过了。它有点可行,但我刚刚注意到通常会进行大量的SPWeb/SPSite.Disposes操作(断点至少命中10次),但这并不改变它能够正常工作的事实。标记为已接受。 - Michael Stum

0
在您的自定义代码中,请确保您没有获取上下文对象的实际SPWeb对象的引用并将其处理掉。例如,以下代码非常糟糕。
using (SPWeb myWeb = SPContext.Current.Web)
{
   // do something
}

这将导致SPContext对象被处理并且可能不会在您的代码中引起问题,但是很可能会在以后引起问题。


我知道。这里的问题是Web在5个类之间传递,而且在其中某个地方有一个非常深层嵌套且难以找到的Dispose(),因此我不知道它是否在我的代码中,因此需要在dispose()上设置一个通用断点以获取调用堆栈。 - Michael Stum

-1

1
你应该仅释放实际创建的SPWeb/SPSite。不应释放SPContext.Current.Web/Site,否则会出现问题,也就是我们所说的Yellow Screen of Death,因为Sharepoint再次尝试使用它的SPWeb时会出现这种情况。那就是我遇到的问题,并且也是我提问的重点。 - Michael Stum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接