gpt4 book ai didi

c# - 在我无法显式调用 Dispose() 的语句中间创建的 IDisposable 对象会怎样?

转载 作者:行者123 更新时间:2023-11-30 13:14:09 25 4
gpt4 key购买 nike

假设我正在使用 Sharepoint(这也适用于其他对象模型),在我的语句中间,我调用了一个方法,在本例中为“OpenWeb()”,它创建了一个 IDisposable SPWeb 对象。现在,我无法在 SPWeb 对象上调用 Dispose(),因为我没有对它的引用。 那么我需要担心这种内存泄漏吗?

SPUser spUser = SPControl.GetContextSite(HttpContext.Current).OpenWeb().SiteUsers[@"foo\bar"];

我知道我可以将语句分成多行并获取调用 Dispose 的 SPWeb 引用:

SPWeb spWeb = SPControl.GetContextSite(HttpContext.Current).OpenWeb();
SPUser spUser = spWeb.SiteUsers[@"foo\bar"];
spWeb.Dispose();

请记住,我的问题不是关于美学,而是更多关于 IDisposable 对象发生了什么,我无法显式调用 Dispose(),因为我没有引用。

抱歉,我第一次问这个问题时不够清楚。从那以后我改写了它。感谢到目前为止的所有回复。

最佳答案

“我无法显式调用 Dispose() 的 IDisposable 对象会发生什么情况?”

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

一般来说,.Net 对象将遵循 these lines 的模式。该模式是定义一个终结器,在未调用 dispose 的情况下清除内容,然后 dispose 抑制终结器。这减少了内存负载并减少了 GC 要做的工作。

在从终结器调用 Dispose 的许多问题中,您正在将单线程问题变成多线程问题,终结器将在不同线程上运行,这会暴露一些非常微妙和很难捕捉到错误。此外,这意味着您将持有非托管资源的时间超过预期(例如,您打开一个文件,忘记调用 close 或 dispose,下次打开它时它已锁定)

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

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

编辑/问题

根据 MS documentation,您不应该对引用调用处置以共享由 GetContextSite 返回的共享点共享对象。所以,你在这里应该格外小心。

请参阅 this answer 了解您应该使用的安全共享点模式。

However, if you have a reference to a shared resource, such as when the object is provided by the GetContextSite method in a Web Part, do not use either method to close the object. Using either method on a shared resource causes an Access Violation error to occur. In scenarios where you have a reference to a shared resource, instead let Windows SharePoint Services or your portal application manage the object.

关于c# - 在我无法显式调用 Dispose() 的语句中间创建的 IDisposable 对象会怎样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/415313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com