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