我在.NET 1.1 SharePoint 2003环境中使用了以下代码,效果很好:
try
{
site = SPControl.GetContextSite(Context);
web = site.OpenWeb();
...
}
catch (Exception export)
{
output.Write("Caught Exception: <br/><br/>");
output.Write(export.Message + "<br><br>");
output.Write(export.StackTrace);
}
finally
{
if (web != null)
web.Dispose();
if (site != null)
site.Dispose();
}
但是,我目前正在将代码移植到.NET 2.0 SharePoint 2007环境中,并收到以下错误消息:
“尝试使用已关闭或处置且不再有效的SPWeb对象。”
如果我注释掉Dispose()代码,它可以正常工作。但这不会导致内存泄漏吗?解决问题的最佳方法是什么?
答案 0 :(得分:2)
当您从GetContextSite获取SPSite对象时,您将获得一个与该页面上运行的所有其他对象共享的对象。
在您处理它之后,其他代码正在尝试使用它 - 因此错误。
您应该只处理自己创建的对象,而不是使用GetContextSite获得的对象。
快速修复是(正如Iambriansreed所说)是删除finally块并用。替换前两行。
SPSite site = SPContext.Current.Site; // Do you even need this?
SPweb web = SPContext.Current.Web;
更好的性能和无内存泄漏,因为SharePoint框架处理通过SPContext检索的对象的创建和处理。
然而 - 这是一个复杂且难以理解的主题,所以彻底阅读Best Practices: Using Disposable Windows SharePoint Services Objects并使用SPDisposeCheck tool是必不可少的。
答案 1 :(得分:1)
处理一次性对象时,特别是SharePoint,使用using
:
using(SPSite site = new SPSite("..."))
using(SPWeb web = site.OpenWeb("..."))
{
}
但是,请注意,您不应该处理来自当前上下文的元素 - 它们是共享的,并且处理它们可能会导致此错误。这是一个常见的错误,在我看来应该由API更好地处理。
另见 - Using Disposable Windows SharePoint Services Objects:
SPContext对象由SharePoint框架管理,不应在代码中明确处理。对于SPContext.Site,SPContext.Current.Site,SPContext.Web和SPContext.Current.Web返回的SPSite和SPWeb对象也是如此。
答案 2 :(得分:1)
这也是更好的方法:
site = SPControl.GetContextSite(Context);
web = site.OpenWeb()
如下:
SPSite site = SPContext.Current.Site;
SPweb web = SPContext.Current.Web;
这里没有内存泄漏。 说真的;去2007年不是2010年?
答案 3 :(得分:0)
将代码放入using语句中,当对象超出范围时将自动调用dispose。
using(site = SPControl.GetContextSite(Context))
{
using(web = site.OpenWeb())
{
//your code
}
}