我一直在就这个话题进行辩论。我检查了几个博客,并使用SPDisposeChecker.exe进行了一些测试。似乎有关于何时必须调用Dispose()的各种想法。例如Christian Glessner撰写的这篇博客:
http://www.ilovesharepoint.com/2010/03/sharepoint-disposing-myths.html
表示没有必要随时使用SPWeb处理网页。
但Microsoft最佳做法建议Dispose任何Openweb。 http://msdn.microsoft.com/en-us/library/aa973248(v=office.12).aspx
在下面的代码块(有点旧并且不在Using块中)::
try
{
SPSite site = new SPSite("http://mysite.aspx");
web = site.OpenWeb();
site.Dispose();
site = null;
}
catch (System.IO.FileNotFoundException x)
{
return;
}
如果我使用SPDisposeCheck快速检查,则会出错:
“一次性类型未处置”在web = site.OpenWeb();
的行上但是当我把一个finally块放在一起时:
finally
{
if (web != null)
web.Dispose();
}
SPDisposeCheck给出以下错误: “注意:不应该在此对象上调用Dispose”
进行一些研究我发现SPDispose有一些错误,正如本博客所解释的
所以我的研究仍然不满意。我的意思是偏离微软的最佳实践是好的,建议总是Dispose()。但是,对于何时何时不处理,我仍然不完全满意。
另外“当您处理SPSite时,它会循环遍历”m_openedWebs“中的所有SPWebs并在每个上调用Close方法”这是一个正确的声明吗?
回到我的代码块是SPWeb.Dispose(在finally块上)真的需要吗?
答案 0 :(得分:1)
我是SharePoint的MCSD,我在SharePoint上做了很多维护编程。在涉及到SharePoint API时,我倾向于保守,因为我经历了他们的进化并且已经看到了他们不断增长的痛苦。
我给你的建议是,如果你打开一个网页(或其他一次性SharePoint对象),那么一旦你完成它就立即处理它是你的最佳利益。即使是自动处理SPWebs的情况,回收该对象的资源可能符合您的最佳利益。如果一个站点有1,000个网站,你想在迭代它们时让它们全部打开吗?可能不是。显然,如果你收到一个上下文对象,你应该把它们放在一起 - 你不是在创建它们,所以它们并不是你真正的责任。
The best practice for SPSite.OpenWeb说“(OpenWeb返回的SPWeb)没有存储在SPSite对象中,也没有在SPSite类的任何地方丢弃。因此,你应该处理通过这些方法创建的任何对象。所以我不确定如何将它添加到m_openedWebs
。所以,关于你的问题,“当你处理SPSite时,它循环遍历”m_openedWebs“中的所有SPWebs,并在每个上调用Close方法”是这是一个正确的陈述吗?“是的,从技术意义上说,这是正确的。你能依靠m_openedWebs来包含你打开的每个网站吗?可能不是。所以我会添加finally块并确保SPWeb被正确处理掉。
答案 1 :(得分:0)
在运行功能的事件处理程序时,不应丢弃您未创建的SPSite / Web,最明显的是SPContext.Current
或传递给您的站点/ Web。
其他时间你应该处理它,通常使用using
是最容易的。
答案 2 :(得分:0)
我注意到并非所有东西都关闭并像文档保证一样处理。例证:使用Ole对象时,Microsoft JET或ACE Acces不会关闭连接。
以下讨论适用于正确实施IDispose
的项目:
我发现的一件事是,如果我只是定期访问一个方法(一小时左右),我可以等待垃圾收集器(GC)为我处理该项目。 / p>
如果我正在进行一个会迭代多个项目的调用,那么在我完成它时,最好实际调用我创建的对象上的Dispose()
。
所以,我想这一切都归结为你在代码中如何使用它。
我希望这会有所帮助。但这并不是一个答案。