使用已处置的 SPSite 和 SPWeb 对象

发布于 2024-10-17 12:19:49 字数 1254 浏览 0 评论 0原文

我很高兴继承了一个写得很糟糕的 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 属性正在用于此操作。那么如何才能发挥作用呢?

I was happy enough to have inherited a terribly written SharePoint project.
Apparently, the original developer was a big fan of reusable code (30% of code is reused across 20 projects without using any libraries—guess how?).

I would often find his code calling some Common.OpenWeb method to retrieve SPWeb object for operating SharePoint stuff. Most of this function's incarnations look exactly the same:

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;
}

And now I'm really worried.
How come this works in production? This method always returns a disposed object, right?

How unstable is it, exactly?

UPDATE:

This method is used in the following fashion:

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;

I omitted the swallowing try-catch for brevity.
This code inserts value into the list! This is a write operation, I'm pretty sure Request property is being used for this. Then how can it work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红玫瑰 2024-10-24 12:19:49

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

现在,经过一番挖掘后,SharePoint 对象似乎并不遵循该规则。 SPWeb 在被处置后不仅不会抛出 ObjectDisposeException,而且实际上在其 Request 属性中测试这种情况如果已被释放,则从其内部状态重建有效的SPRequest

看来至少 SPWeb 的设计是即使在废弃状态下也能完全发挥作用。为什么,我不知道。也许它是为了容纳像您正在处理的那样的客户端代码。也许这是某种我无法理解的复杂优化。

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

当然,您仍然会泄漏新的 SPRequest 实例,这可能会造成相当大的成本。永远、永远不要使用已处置的对象,即使 SharePoint 允许您逃脱惩罚。

First, the short answer: that method indeed returns a disposed object. An object should not be used after being disposed, because it's no longer in a reliable state, and any further operation performed on that object should (theoretically) throw an ObjectDisposedException.

Now, after digging a little, SharePoint objects don't seem to follow that rule. Not only does SPWeb never throw ObjectDisposedException after being disposed, but it actually tests for that case in its Request property and rebuilds a valid SPRequest from its internal state if it has been disposed.

It seems that at least SPWeb was designed to be fully functional even in a disposed state. Why, I don't know. Maybe it's for accommodating client code like the one you're working on. Maybe it's some kind of complicated optimization I can't possibly understand.

That said, I'd suggest you don't rely on that behavior, because it might change in the future (even though, given Microsoft's policy on bug-for-bug backwards compatibility, it might not).

And of course, you will still leak the new SPRequest instance, which can be quite costly. Never, ever, use a disposed object, even if SharePoint lets you get away with it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文