当前位置:  开发笔记 > 编程语言 > 正文

在语句中间创建的IDisposable对象会发生什么,我无法明确地调用Dispose()?

如何解决《在语句中间创建的IDisposable对象会发生什么,我无法明确地调用Dispose()?》经验,为你挑选了1个好方法。

假设我正在使用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(),因为我没有引用.

很抱歉在我第一次提出问题时不够清楚.我已经改写了它.感谢到目前为止的所有回复.



1> Sam Saffron..:

"IDisposable对象会发生什么,我无法显式调用Dispose()?"

通常,您可以在所有一次性对象上调用Dispose(隐式使用using语句或显式),但是在您不能的假设场景中,它取决于对象的实现方式.

通常,.Net对象将遵循这些行的模式.该模式是定义一个终结器,在没有调用dispose的情况下清除东西,然后使用dispose来抑制终结器.这减少了内存负载,并减少了GC的工作量.

从终结器中调用Dispose的许多问题之一是,您将单线程问题转变为多线程问题,终结器将在不同的线程上运行,这可能会暴露一些非常微妙且难以捕获的错误.此外,这意味着您将持续超过预期的非托管资源(例如,您打开文件,忘记致电关闭或处置,下次再打开它锁定)

重要的是,处理所有一次性物品是最佳做法,否则你可能会引入奇怪而复杂的错误.需要注意的是,某些框架(如sharepoint)会返回不应根据文档处理的对象的共享实例.

当我使用"using"模式处理对象时,我通常会发现代码更具可读性.显式调用Dispose(object.Dispose())的问题在于,很难跟踪对象的分配位置,并且很容易忘记.你不能忘记关闭using语句的大括号,编译器会抱怨:)

编辑/ GOTCHA

根据MS文档,您不应该对GetContextSite返回的共享点共享对象的引用调用dispose.所以,你应该格外小心.

有关您应该使用的安全共享点模式,请参阅此答案.

但是,如果您具有对共享资源的引用,例如,当Web部件中的GetContextSite方法提供该对象时,请不要使用任何一种方法来关闭该对象.在共享资源上使用任一方法都会导致发生访问冲突错误.在您引用共享资源的情况下,请让Windows SharePoint Services或门户网站应用程序管理该对象.

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有