我很高兴继承了一个写得非常好的SharePoint项目 显然,最初的开发人员是可重用代码的忠实粉丝(30%的代码在不使用任何库的情况下在20个项目中重用 - 猜猜怎么样?)。
我经常会发现他的代码调用了一些Common.OpenWeb
方法来检索用于操作SharePoint内容的SPWeb
对象。这个功能的大部分内容看起来完全一样:
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
属性正在用于此。那又怎么样呢?
答案 0 :(得分:12)
首先,简短的回答:该方法确实返回一个已处置的对象。处置后不应使用对象,因为它不再处于可靠状态,并且对该对象执行的任何进一步操作应(理论上)抛出ObjectDisposedException。
现在,在挖掘一点之后,SharePoint对象似乎不遵循该规则。 SPWeb
不仅在处置后永远不会抛出ObjectDisposedException
,而是在其Request
属性和重建中实际测试如果已被处置,则来自其内部状态的有效SPRequest
。
似乎至少SPWeb
设计即使在处置状态下也能完全正常运行。为什么,我不知道。也许这是为了容纳你正在处理的客户端代码。也许这是一种我无法理解的复杂优化。
那就是说,我建议你不要依赖那种行为,因为它可能会在未来发生变化(尽管,考虑到微软关于bug-for-bug向后兼容性的政策,它可能不会。)
当然,您仍然会泄漏新的SPRequest
实例,这可能会非常昂贵。永远不要使用已处置的对象,即使SharePoint可以让你逃脱它。