子类终结器

时间:2018-08-15 21:07:03

标签: c# singleton subclass idisposable

我有一个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属性跟踪实例总数,该属性由工厂增加。处理完最后一个实例后,该卡就关闭了,但是事实证明这种方法不可靠。

0 个答案:

没有答案