通过设置为空来处置?

时间:2011-10-18 09:44:24

标签: c# .net idisposable

我知道以传统方式处理IDisposable的技术。比如,在Windows服务的OnStop()方法中我关闭了消息队列客户端:

        if (client != null)
        {
            client.Dispose();
        }

今天我第一次看到一个人这样做:

        using (client)
        {
            client = null;
        }

他的“使用”内部究竟发生了什么,或者他是否正确处置?

5 个答案:

答案 0 :(得分:6)

using(){}语句获取引用var的副本,因此使用null进行此分配无效。

答案 1 :(得分:4)

您的基于using的同事的代码会起作用,但可能有点矫枉过正;

using(client) {
    client = null;
}

基本上是:

{ // scope here to denote that 'tmp' is not defined outside this scope
  var tmp = client;
  try {
      client = null;
  } finally {
      if(tmp != null) tmp.Dispose();
  }
}

(不是相当,在所有情况下,因为有值类型和显式接口实现需要考虑)。

就个人而言,我只会在可能的情况下使用using(即在最初分配客户端的代码中)。

有一次我可能会使用这个是懒惰的:

using(client as IDisposable) { client = null; } // dispose if needed

即。 client是我无法控制的,我不确定它是否实现IDisposable,但如果确实如此,我需要释放它。

答案 2 :(得分:3)

退出

using (client)
{
}
系统会自动为您调用

client.Dispose() 在我看来,应该从该代码中调出client = null 请记住,要使用using(object),对象应实现IDisposable接口。

答案 3 :(得分:0)

对我而言,它看起来根本没有效果。由于客户端设置为null,因此即使实际对象仍然在内存中,也没有引用任何变量引用,因为它不会被任何变量引用(稍后将对其进行垃圾回收,但是使用的重点是什么? )。

答案 4 :(得分:0)

如果“client”的范围扩展到“using”块之外,就像它所看到的那样,写入的代码将确保在控制离开“using”块之前“客户端”被释放,并且引用新发布的“客户”对象将被销毁。如果它是一个字段,则取消对它的引用可能很重要,如果它是一个附加事件的属性,则可能是关键的。

我的猜测是“客户”是一个字段或属性,“使用”代码的作者认为它比Marc Gravell给出的版本更简洁。我会授予作者代码简洁,但会建议更简洁,更清晰的是定义一个通用的“Zap”例程,它接受一个I​​Disposable 引用,使用Interlocked.Exchange来读取并将其置零,如果它不为null则处置它。在这种情况下,“using”语句将替换为:

  Zap(ref client);

这有利于更简洁,但几乎肯定更清晰。