是否总是需要调用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块上),这里真的需要吗?

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

我是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()

所以,我想这一切都取决于你如何在代码中使用它。

我希望这能有所帮助。不过,这并不是一个很大的答案。