假设我正在使用Sharepoint(这也适用于其他对象模型)并且在我的语句中间,我调用了一个方法,在本例中为"OpenWeb()",它创建了一个IDisposable SPWeb对象.现在,我无法在SPWeb对象上调用Dispose(),因为我没有对它的引用. 那么我需要关注这个泄漏的记忆吗?
SPUser spUser = SPControl.GetContextSite(HttpContext.Current).OpenWeb().SiteUsers[@"foo\bar"];
我知道我可以将语句拆分成多行并获取SPWeb引用来调用Dispose:
SPWeb spWeb = SPControl.GetContextSite(HttpContext.Current).OpenWeb(); SPUser spUser = spWeb.SiteUsers[@"foo\bar"]; spWeb.Dispose();
请记住,我的问题不是关于美学,而是关于IDisposable对象发生了什么,我无法明确地调用Dispose(),因为我没有引用.
很抱歉在我第一次提出问题时不够清楚.我已经改写了它.感谢到目前为止的所有回复.
"IDisposable对象会发生什么,我无法显式调用Dispose()?"
通常,您可以在所有一次性对象上调用Dispose(隐式使用using语句或显式),但是在您不能的假设场景中,它取决于对象的实现方式.
通常,.Net对象将遵循这些行的模式.该模式是定义一个终结器,在没有调用dispose的情况下清除东西,然后使用dispose来抑制终结器.这减少了内存负载,并减少了GC的工作量.
从终结器中调用Dispose的许多问题之一是,您将单线程问题转变为多线程问题,终结器将在不同的线程上运行,这可能会暴露一些非常微妙且难以捕获的错误.此外,这意味着您将持续超过预期的非托管资源(例如,您打开文件,忘记致电关闭或处置,下次再打开它锁定)
最重要的是,处理所有一次性物品是最佳做法,否则你可能会引入奇怪而复杂的错误.需要注意的是,某些框架(如sharepoint)会返回不应根据文档处理的对象的共享实例.
当我使用"using"模式处理对象时,我通常会发现代码更具可读性.显式调用Dispose(object.Dispose())的问题在于,很难跟踪对象的分配位置,并且很容易忘记.你不能忘记关闭using语句的大括号,编译器会抱怨:)
编辑/ GOTCHA
根据MS文档,您不应该对GetContextSite返回的共享点共享对象的引用调用dispose.所以,你应该格外小心.
有关您应该使用的安全共享点模式,请参阅此答案.
但是,如果您具有对共享资源的引用,例如,当Web部件中的GetContextSite方法提供该对象时,请不要使用任何一种方法来关闭该对象.在共享资源上使用任一方法都会导致发生访问冲突错误.在您引用共享资源的情况下,请让Windows SharePoint Services或门户网站应用程序管理该对象.