是否总是需要调用SPSite.dispose()和SPWeb.dispose()?

时间:2013-02-07 20:14:04

标签: c# .net sharepoint dispose

我一直在就这个话题进行辩论。我检查了几个博客,并使用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有一些错误,正如本博客所解释的

http://social.msdn.microsoft.com/Forums/is/sharepointdevelopmentlegacy/thread/3fe362b3-cc03-43e5-a076-bf37dd8175c9

所以我的研究仍然不满意。我的意思是偏离微软的最佳实践是好的,建议总是Dispose()。但是,对于何时何时不处理,我仍然不完全满意。

另外“当您处理SPSite时,它会循环遍历”m_openedWebs“中的所有SPWebs并在每个上调用Close方法”这是一个正确的声明吗?

回到我的代码块是SPWeb.Dispose(在finally块上)真的需要吗?

3 个答案:

答案 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()

    < / LI>

所以,我想这一切都归结为你在代码中如何使用它。

我希望这会有所帮助。但这并不是一个答案。