通过设置为 null 来处理?

发布于 2024-12-10 06:06:43 字数 336 浏览 1 评论 0原文

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

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

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

        using (client)
        {
            client = null;
        }

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

I'm aware of technique to handle IDisposable in a traditional manner. Say, in OnStop() method of windows service I close message queue client:

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

For the first time today I saw one guy doing that this way:

        using (client)
        {
            client = null;
        }

What is exactly happening inside his "using" or does he dispose correctly at all?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柏林苍穹下 2024-12-17 06:06:43

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

The using(){} statement grabs a copy of the reference var so this assignment with null is ineffective.

っ左 2024-12-17 06:06:43

您基于 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 ,但如果它实现了,我需要释放它。

Your using-based colleague's code will work, but is arguably overkill;

using(client) {
    client = null;
}

is essentially:

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

(not quite that in all cases, as there are value-types and explicit interface implementation to think about).

Personally, I'd just use using for the whole thing where possible (i.e. in the code that initially allocates client).

One time I might use this is a lazy:

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

i.e. client is something outside my control, and I'm not sure if it implements IDisposable or not, but if it does, I need to release it.

少女的英雄梦 2024-12-17 06:06:43

退出

using (client)
{
}

系统会自动为您调用 client.Dispose()
我认为 client = null 应该从该代码中调用。
请记住,要使用 using(object) 对象应实现 IDisposable 接口。

Exiting from

using (client)
{
}

client.Dispose() is called automatically for you.
client = null should be called out of that code in my opinion.
Remember that to use using(object) the object should implement IDisposable interface.

時窥 2024-12-17 06:06:43

对我来说,它看起来根本没有效果。由于客户端设置为 null,因此 using 不再有任何引用可以处置,即使实际对象仍在内存中,只是没有被任何变量引用(稍后它将被垃圾收集,但是 using 的意义何在? )。

To me it looks not effective at all. Since the client is set to null the using has nothing referenced to dispose anymore, even though the actual object is still in memory, just not referenced by any variable (it will be garbage collected later on, but what's the point of the using then?).

失退 2024-12-17 06:06:43

如果“client”的范围扩展到“using”块之外,那么所编写的代码将确保“client”在控制离开“using”块之前被释放,并且对新失效的块的引用“客户端”对象将被销毁。如果它是一个字段,则清空对其的引用可能很重要;如果它是附加事件的属性,则可能很关键。

我的猜测是“client”是一个字段或属性,“using”代码的作者认为它比 Marc Gravell 给出的版本更简洁。我承认作者的代码很简洁,但建议更简洁、更清晰的是定义一个通用的“Zap”例程,它接受 IDisposable 通过引用,使用 Interlocked.Exchange 来读取并将其设置为空,如果不为空则将其丢弃。在这种情况下,“using”语句将被替换为:

  Zap(ref client);

其优点是更简洁,同时几乎肯定更清晰。

If the scope of "client" extends outside the "using" block, as it would appear to, the code as written will ensure that "client" gets disposed before control leaves the "using" block, and the reference to the newly-defunct "client" object will be destroyed. Nulling out the reference to it may be important if it's a field, and may be critical if it's a property that attaches events.

My guess would be that "client" is a field or property, and that the author of the "using" code thought it was more concise than the version given by Marc Gravell. I would grant the author that the code is concise, but would suggest that even more concise and clearer would be to define a generic "Zap" routine which accepts an IDisposable by reference, uses Interlocked.Exchange to read and null it, and disposes it if it wasn't null. In that case, the "using" statement would be replaced with:

  Zap(ref client);

which has the benefit of being more concise while almost certainly being clearer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文