c# - 子类终结器
问题描述
我有一个 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
如您所见,我正在尝试使用由工厂递增的属性来跟踪总实例数。当最后一个实例被处理时,卡被关闭,但这种方法被证明不太可靠。
解决方案
推荐阅读
- logstash - _grokparsefailure 使用多个 grok 过滤器在所有已解析日志中标记
- r - r中具有不同变量条件的循环线性模型
- javascript - 两个 mat-gird-list 排成一行时重叠
- extjs - 我怎么能关闭 Extjs 7 的 SDK
- vue.js - 使用 Vue CLI 和 Vuetify 导入全局 scss 变量
- windows - 在 Windows 10 上找不到使用某个端口的进程
- c# - 如何在 C# 中使用鼠标移动和更改形状的大小
- java - 线程池 - java.util.concurrent.RejectedExecutionException
- verilog - 如何在verilog中实现“posedge异步复位逻辑”?
- html - 更改 Bootstrap 4 下拉按钮颜色