4

我很高兴继承了一个写得很糟糕的 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;
}

现在我真的很担心。
这如何在生产中起作用?这个方法总是返回一个已处理的对象,对吧?

它到底有多不稳定?

更新:

此方法以下列方式使用:

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;

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

4

1 回答 1

12

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

现在,在深入挖掘之后,SharePoint 对象似乎并不遵循该规则。不仅在被处理后SPWeb不会抛出ObjectDisposedException异常,而且它实际上会在其属性中测试该案例,并在其已被处理时从其内部状态重建一个有效值。RequestSPRequest

似乎至少SPWeb设计成即使在处置状态下也能完全发挥作用。为什么,我不知道。也许它是为了适应您正在处理的客户端代码。也许这是某种我无法理解的复杂优化。

也就是说,我建议您不要依赖这种行为,因为它将来可能会改变(即使考虑到微软关于 bug-for-bug 向后兼容性的政策,它可能不会)。

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

于 2011-02-14T21:06:06.820 回答