将SqlConnection的得到处理的GC? [英] Will SqlConnection get disposed by GC?

查看:144
本文介绍了将SqlConnection的得到处理的GC?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

免责声明:我知道的IDisposable 应在与非托管资源处理来实现。的code的其余部分应是确定性的,做使用(...){} 相当于尝试{} {最终处置( );} ),以尽快保证清理。此外,GC将不叫的Dispose() ,所以推荐的模式(使用析构函数的语法在C#)重写的Finalize()的方法,然后调用的Dispose()。 GC将通常所说的的Finalize()(除非 GC.Sup pressFinalize()已被调用)。

Disclaimer: I know IDisposable should be implemented when dealing with unmanaged resources. The rest of the code should be deterministic and do using (...) { } (equivalent of try {} finally { Dispose(); }) to guarantee a cleanup as soon as possible. Also, the GC will not call Dispose(), so the recommended pattern is to override the Finalize() method (in C# using the destructor syntax) which then calls Dispose(). The GC will usually call Finalize() (unless GC.SuppressFinalize() has been called).

问题:所以,现在,我得到了这一点的方式,我有一个奇怪的场景,我不能这样做使用(SqlConnection的...){} 由于code在我的掌握。我通常可以做一个确定性的的Dispose(),但不能保证。我使用反射来拆卸的SqlConnection ,并看到它使用的Dispose(),但是,除非我很盲目的,没有终结/析构函数(的Finalize() 〜的SqlConnection())。这是否意味着GC将不是清理(发送回池)在奇数情况下,我无法连接?我一直没能找到任何明确的...

Problem: So now that I got that out of the way, I have an odd scenario where I cannot do using (SqlConnection...) { } due to code out of my control. I can usually do a deterministic Dispose(), but can't guarantee it. I used Reflector to disassemble SqlConnection and see that it uses Dispose(), but unless I'm blind there is no finalizer/destructor (Finalize() or ~SqlConnection()). Does that mean that the GC will not "clean up" (send back to the pool) the connection in the odd case I can't? I haven't been able to find anything definitive...

推荐答案

那么,它不会得到处置,最终确定为不处理。

Well, it won't get disposed, as finalisation is not disposal.

有一个在 System.ComponentModel.Component A finaliser,但其SUP pressed在的SQLConnection 构造函数。这是一个好主意,如果你的东西,你知道100%的把握,你将不再需要finaliser继承,又是个坏​​主意,否则。在这种情况下,它是一个好主意。

There is a finaliser in System.ComponentModel.Component, but its suppressed in SQLConnection's constructor. This is a good idea if you inherit from something with a finaliser that you know with 100% certainty you won't need, but a bad idea otherwise. In this case it's a good idea.

但请记住,这的SqlConnection 是一个真正的连接的包装。事实上,这是最有可能在了一组重present不同的连接状态的对象更改包装。这是允许的真实连接被有效地汇集机制的一部分,因为每次调用时间打开()它从池相关的对象,每次打电话关闭()(无论是直接通过的Dispose()或离开的范围使用)返回它。

Remember though, that SqlConnection is a wrapper on a "real" connection. Indeed, it's most likely a wrapper on a changing set of objects which represent different connection states. This is part of the mechanism that allows for the "real" connection to be pooled efficiently, as each time you call Open() it obtains the relevant object from the pool, and every time you call Close() (whether directly, by Dispose() or by leaving the scope of a using) it returns it.

现在,请记住,这直接持有非托管资源或东西,否则没有GC的关注只对象,需要完成。 的SqlConnection 持有的对象,可能会(视的SqlConnection 的状态)是一个拥有非托管资源(或实际上通过类鸟巢)深。因此,没有必要的SqlConnection 来自己完成。考虑三种可能的方法是打开的SqlConnection 可以不再是一个开放的的SqlConnection

Now, remember that only objects that directly hold an unmanaged resource or something otherwise not the GC's concern, need to be finalised. SqlConnection holds an object that may (depending on the state of SqlConnection) be one that holds an unmanaged resource (or indeed, deeper through the nest of classes). There is therefore no need for SqlConnection to itself be finalised. Consider the three possible ways an open SqlConnection can stop being an open SqlConnection:

  1. 关闭()被调用。这立即返回到池的实际连接(或关闭它,如果没有池)。
  2. 的Dispose()被调用。这就要求关闭()有同样的效果。
  3. 在该对象获得垃圾回收。
  1. Close() is called. This immediately returns the real connection to the pool (or closes it if there is no pooling).
  2. Dispose() is called. This calls Close() with the same effect.
  3. The object gets garbage collected.

现在,在第三种情况下,在对象包含一个引用到具有实际的连接的对象。这也就是这样做的唯一对象。该对象,因此也将被垃圾收集。如果它有一个finaliser(它可能确实,虽然我不会去假设不会有进一步的聪明招数怎么回事),那么finaliser将导致它被放置在finaliser队列中,并最终将敲定。

Now, in the third case, the object holds a reference to the object that has the real connection. It also is the only object that does so. That object is hence also going to be garbage collected. If it has a finaliser (which it probably does, though I'm not going to assume there aren't further clever tricks going on) then that finaliser will cause it to be placed into the finaliser queue, and it will be eventually finalised.

如果的SqlConnection 有finaliser,唯一真正的影响将是:

If SqlConnection had a finaliser, the only real effects would be:

  1. 潜力马车code(处理中finaliser code finalisable成员充满,因为你不知道他们是否已经完成)。
  2. 潜在减缓东西(真正的连接将被反正敲定,充其量我们只是放慢了最后定稿和GC)。
  3. 没有在这里做呢(真正的连接将没有任何帮助,在这里完成)。

所以,把一个finaliser的的SqlConnection 是无一胜一赔。此外,实际的连接应该有希望被最终敲定。

So, putting a finaliser on the SqlConnection is a lose without a win. Also, your real connection should hopefully be eventually finalised.

这表示,它仍然很不理想,仍然非常可能发生泄漏的连接。你能否详细precisely为什么你不能叫关闭()或处置自己?可以在code管理连接不紧密打电话给你(的对象应该结束其天的地方的,而应先关闭存在)?

This said, it's still far from ideal and still very likely to leak connections. Could you detail precisely why you can't call Close() or dispose yourself? Could the code managing the connection not call close for you (the object should end its days somewhere, and should be closed there)?

你需要保持它活着的的IDataReader 或对象的饲料从的IDataReader 被允许去完成?在这种情况下,可以使用 CommandBehavior.CloseConnection 标记,以便关闭(或处置)的阅读器关闭连接?这后一种情况下是在哪里我能记得曾经有让连接离开范围未处置的唯一情况。

Do you need to keep it alive for an IDataReader or an object that feeds from an IDataReader to be allowed to complete? In which case, could you use the CommandBehavior.CloseConnection flag so that closing (or disposing of) the reader closes the connection? This latter case is about the only case where I can recall ever having to let a connection leave scope un-disposed.

这篇关于将SqlConnection的得到处理的GC?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆