是否总是需要调用SPSite.dispose()和SPWeb.dispose()
本文关键字:dispose SPWeb SPSite 调用 是否 | 更新日期: 2023-09-27 17:58:27
我已经就这个话题争论了好几天了。我查看了几个博客,并使用SPDisposeChecker.exe进行了一些测试。关于何时必须调用Dispose(),似乎有各种各样的想法。例如Christian Glessner的博客:
http://www.ilovesharepoint.com/2010/03/sharepoint-disposing-myths.html
表示没有必要一直使用SPWeb处理web。
但是,Microsoft最佳实践建议处置任何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
{
if (web != null)
web.Dispose();
}
SPDisposeCheck给出以下错误:"注意:不应对此对象调用Dispose"
做了一点研究,我发现SPDispose有一些错误,正如这个博客所解释的那样
http://social.msdn.microsoft.com/Forums/is/sharepointdevelopmentlegacy/thread/3fe362b3-cc03-43e5-a076-bf37dd8175c9
所以我对自己的研究还是有点不满意。我的意思是,遵循微软的最佳实践是很好的,它建议始终使用Dispose()。然而,我仍然不完全满意何时以及何时不进行处置。
此外,"当您处置SPSite时,它会循环通过"m_openedWebs"中的所有SPWeb,并在每个SPWeb上调用Close方法",这是正确的说法吗?
回到我的代码块是SPWeb.Dispose(在finally块上),这里真的需要吗?
我是SharePoint的MCSD,在SharePoint上做了很多维护编程。当谈到SharePoint API时,我倾向于保守,因为我经历了它们的演变,也看到了它们成长的许多痛苦。
我给你的建议是,如果你打开了一个网站(或其他SharePoint一次性对象),你最好在处理完后立即处理它。即使SPWeb是自动处理的,回收该对象的资源也可能符合你的最佳利益。如果一个网站有1000个网站,你想在迭代时保持它们都打开吗?可能不会。显然,如果你正在接收一个上下文对象,你应该把它们放在一边——你不是在创建它们,所以它们实际上不是你的责任。
SPSite.OpenWeb的最佳实践是"(OpenWeb返回的SPWeb)没有存储在SPSite对象中,也没有在SPSite类中的任何位置进行处理。因此,您应该处理通过这些方法创建的任何对象。因此,我不确定它将如何添加到m_openedWebs
中。因此,关于您的问题,"当您处理SPSite时,它会循环通过"m_openedWebs",并在每个"这是一个正确的语句吗?"上调用Close方法,是的,从技术意义上讲,这是正确的。你能依靠m_openedWeb来包含你打开的每个网站吗?可能不会。因此,我会添加finally块,并确保SPWeb得到正确处理。
您不应该处理您没有创建的SPSite/Web,尤其是SPContext.Current
或在运行功能的事件处理程序时传递给您的site/Web。
剩下的所有时间都应该处理掉,通常使用using
是最简单的。
我注意到,并不是所有的东西都像文档保证一样关闭和处理。举个例子:Microsoft JET或ACE Acces在使用Ole对象时不会关闭连接。
以下讨论针对正确实现IDispose
的项目:
-
我发现,如果我只打算定期访问一个方法(大约每小时一次),我可以等待垃圾回收器(GC)为我处理该项目
-
如果我正在进行一个将在多个项目上迭代的调用,那么当我完成它时,最好实际调用我创建的对象上的
Dispose()
所以,我想这一切都取决于你如何在代码中使用它。
我希望这能有所帮助。不过,这并不是一个很大的答案。