可以在终结器中使用互锁吗?

时间:2013-03-14 11:34:00

标签: c# finalizer interlocked

假设我需要清理终结器中的一些托管资源,或者至少以线程安全的方式将其记录到需要清理的地方。根据我的理解,在终结器中取锁是严格禁止的,但是Interlocked类怎么样?这样安全并且不会导致死锁吗?

static int deadentries;
~Item() { Interlocked.Increment(ref deadentries); }
public static T Get(int id, Action<T> init) {
    T ret;
    WeakReference<T> tref;
    if (cache.TryGetValue(id, out tref)) {
        if (tref.TryGetTarget(out ret)) return ret;
        else Interlocked.Decrement(ref deadentries);
    }
    if (deadentries * 2 > cache.Count) {
        // etc. etc.

此外,似乎所有终结器都在一个线程上运行,这是一个保证行为还是只是一个实现细节?如果它只是一个细节,那么在终结器中获取锁定是否可以(例如,在无锁队列中推送作业),前提是锁定永远不会被带到其他地方?

1 个答案:

答案 0 :(得分:1)

终结器运行一个线程是一个实现细节(这不太可能改变,因为它会违反MS所坚持的非常严格的兼容性标准。仍然不能依赖)。

锁定在终结器中实际上是正常的。它们可能会成为性能或正确性问题,但这并不是因为它们作为Finalizer的一部分运行。这些是锁的一般属性。 Interlocked类也可以使用。

请记住,终结者可以按任何顺序执行,也可以同时执行。也不是逆依赖顺序,而是随机顺序。