首页 > 解决方案 > 子类终结器

问题描述

我有一个 C# 项目,它调用第 3 方非托管 DLL 来控制 PCI 卡。他们的 API 文档声明CardClose必须在我的应用程序终止之前调用。因为该卡是多功能的,所以我为它编写了两个接口并使用单独的单例类来实现它们。还有一个用于共享通用信息的基类,例如CardHandle, 和用于生成单例实例(工厂模式)。

我的挑战是弄清楚如何在子类中使用终结器在处理类时调用CardClose。但我只希望在两个类都被处理后发生这种情况,否则该卡对仍在使用它的其他类变得不可用。(我意识到您通常不会处理单例,但在这种情况下我有理由这样做。)一种解决方案是将这些类组合成一个,但我很好奇是否有更好的方法。

这是基类的处置代码:

    protected static int CardHandle { get; set; } = -1;
    protected static bool IsAvailable { get; set; } = false;
    protected static uint InstancesCount { get; private set; } = 0;

    #region IDisposable Support
    private bool m_alreadyDisposed = false; // To detect redundant calls

    protected virtual void Dispose(bool disposing) // Overridden by subclasses which should then call base.Dispose(disposing)
    {
        if (m_alreadyDisposed) return;

        if (disposing)
        {
            // Dispose managed state (managed objects). 
        }

        // Free unmanaged resources (unmanaged objects) and override a finalizer below.
        InstancesCount--;
        m_alreadyDisposed = true;
    }

    // Override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
    //~Arinc()
    //{
    //    // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
    //    Dispose(false);
    //}

    public void Dispose()
    {
        // Put cleanup code in Dispose(bool disposing) above.
        Dispose(true); // When overriden, this will call the derived class's Dispose(boolean).
        GC.SuppressFinalize(this);
    }
    #endregion

第一个带有终结器的子类:

    #region IDisposable Support
    private bool m_alreadyDisposed = false; // To detect redundant calls

    protected override void Dispose(bool disposing)
    {
        if (m_alreadyDisposed) return;

        if (disposing)
        {
            // Dispose managed state (managed objects).
            Arinc429Device = null; // This class instance, stored as a property.
        }

        // Free unmanaged resources (unmanaged objects) and override a finalizer below.
        if (InstancesCount == 1) // This is the last instance if true.
        {
            L43_CardReset(CardHandle); // Unmanaged code call.
            L43_CardClose(CardHandle); // Unmanaged code call.
            CardHandle = -1;
            IsAvailable = false;
        }

        m_alreadyDisposed = true;

        base.Dispose(disposing);
    }

    ~Arinc429Ballard()
    {
        // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
        Dispose(false);
    }
    #endregion

第二个子类使用相同的处理代码,但具有不同的实例属性。InstancesCount如您所见,我正在尝试使用由工厂递增的属性来跟踪总实例数。当最后一个实例被处理时,卡被关闭,但这种方法被证明不太可靠。

标签: c#singletonsubclassidisposable

解决方案


推荐阅读