【问题标题】:Passing IDisposable as parameter将 IDisposable 作为参数传递
【发布时间】:2019-03-26 11:56:30
【问题描述】:

在下文中,我将一次性对象作为参数传递给构造函数,然后执行一些操作,仅此而已。构造函数除了设置 DisposableObject 的局部变量实例之外什么也不做。

我是否相信即使在 What() 调用中出现异常时,一次性用品仍会被处置?

如果代码在 for 循环中,则两个对象也会超出范围并被垃圾回收(我的 App Domain 中只能有这个 IDisposable 类的一个实例)。

using (var disposableObject = new DisposableObject()) 
{
    var simpleObject= new Simple(disposableObject);
    simpleObject.Whatever();
}

【问题讨论】:

  • 是的,如果disposableObject 已经创建,实例将被disposed
  • “我的 App Domain 中只能有这个 IDisposable 类的一个实例” 这似乎是一个奇怪的设计选择。
  • 我们不能保证GC(垃圾收集器)会运行(更不用说收集实例了)
  • @Zahar Peled,我同意,但它是第 3 方对象,我无法控制

标签: c# garbage-collection idisposable


【解决方案1】:

澄清一下:IDisposable 不是关于垃圾收集,而是关于资源管理的更大主题。一个简单的例子可能是一个SqlConnection,它被用来释放与数据库的连接。 SqlConnection 对象仍然存在于内存中,并在超出范围后被垃圾回收。

这对您的“每个 AppDomain 一个实例”问题没有帮助,因为对象的生命周期不受您控制。充其量您可以拥有一个未处置的对象。


using 语句实际上是 try-finally 块,finally 始终在其中运行以确保对象已被释放。

这段代码:

using(var disposable = new DisposableObject())
{
    ...
}

基本上等同于这段代码:

var disposable = new DisposableObject();

try
{
    ...
}
finally
{
    disposable?.Dispose();
}

除非对对象的引用丢失,否则始终调用 Dispose。

【讨论】:

  • 您认为什么可能会导致引用“丢失”? disposable(在您的示例中)在 using 的正文中是只读的,因此不能将其分配给 null
  • 谢谢保罗。是的,并不意味着在其中添加了 GC 会使水变得浑浊。 DisposableObject 类实际上是一个第 3 方类,它会抛出一个异常,声称不能有多个实例。我想 100% 我正在编写合法代码。我认为与上面的代码无关的第 3 方类有一些东西。 (由于与问题无关的原因,我还需要多次重新创建课程)
  • @Damien_The_Unbeliever 在try-finally 的情况下,如果您要为disposable 字段分配新值,则原始值将丢失且无法处置。
猜你喜欢
  • 2020-09-18
  • 2015-05-24
  • 2012-11-10
  • 2020-10-30
  • 2014-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多