使用已处置的SPSite和SPWeb对象

Dan*_*mov 4 sharepoint idisposable using spweb

我很高兴继承了一个非常复杂的SharePoint项目.
显然,原始开发人员是可重用代码的忠实粉丝(30%的代码在不使用任何库的情况下在20个项目中重复使用 - 猜怎么样?).

我经常会发现他的代码调用一些Common.OpenWeb方法来检索SPWeb操作SharePoint内容的对象.这个函数的大部分内容看起来完全相同:

public SPWeb OpenWeb()
{
    String strSiteUrl = ConfigurationManager.AppSettings["SiteUrl"].ToString();
    SPSite site = null;
    SPWeb web = null;
    try
    {
        using (site = new SPSite(strSiteUrl))
        {
            using (web = site.OpenWeb())
            {
                return web;
            }
        }
    }
    catch (Exception ex)
    {
        LogEvent("Error occured in OpenWeb : " + ex.Message, EventLogEntryType.Error);
    }
    return web;
}
Run Code Online (Sandbox Code Playgroud)

而现在我真的很担心.
为什么这在生产中有效?这个方法总是返回一个被处理的对象,对吧?

它到底有多不稳定?

更新:

此方法以下列方式使用:

oWeb = objCommon.OpenWeb();
SPList list = oWeb.Lists["List name"];
SPListItem itemToAdd = list.Items.Add();
itemToAdd["Some field"] = "Some value";
oWeb.AllowUnsafeUpdates = true;
itemToAdd.Update();
oWeb.AllowUnsafeUpdates = false;
Run Code Online (Sandbox Code Playgroud)

try-catch为简洁起见,我省略了吞咽.
此代码将值插入列表中!这是一个写操作,我很确定Request属性正在用于此.那又怎么样呢?

Fré*_*idi 12

首先,简短的回答:该方法确实返回一个已处置的对象.处理后不应使用对象,因为它不再处于可靠状态,并且对该对象执行的任何进一步操作应该(理论上)抛出ObjectDisposedException.

现在,在挖掘一点之后,SharePoint对象似乎不遵循该规则.不仅在被处置后SPWeb从不抛出ObjectDisposedException,而且它实际上在其属性中测试该情况,Request并且如果已经处置则从其内部状态重建有效SPRequest.

看来,至少SPWeb设计的全部功能,即使在配置状态.为什么,我不知道.也许这是为了容纳你正在处理的客户端代码.也许这是我无法理解的某种复杂的优化.

也就是说,我建议你不要依赖这种行为,因为它可能会在未来发生变化(尽管,考虑到微软关于bug-for-bug向后兼容性的政策,它可能不会).

当然,您仍然会泄漏新SPRequest实例,这可能非常昂贵.永远不要使用已处置的对象,即使SharePoint可以让您逃脱它.