1

我正在编写一个 ASCOM 望远镜驱动程序,当客户端应用程序无法正确断开连接或崩溃时,我需要保证向示波器发送一些串行端口命令以阻止示波器移动。

我尝试添加一个看起来像这样的终结器

~Telescope()
{
    Common.AbortSlew();
    Common.SetTracking(false);
}

它进入了 SendSerialPortCommand() 方法,然后退出而不实际将字节发送到线路上,并且似乎在锁定语句之前退出。

回购可以在这里查看

http://code.google.com/p/ascom-nexstar-telescope/source/browse/NexStar/

终结器在 driver.cs 中调用的方法在静态类 Common

有没有更好或更可靠的方法来做到这一点?

4

4 回答 4

4

实现IDisposable接口并在 Dispose 方法中完成您的工作。

您应该看到 Greg Beech 的这篇文章:实现和使用 IDisposable 接口

.NET 没有析构函数,而是通过覆盖定义在基 Object 类上的 Finalize 方法来实现终结器(尽管 C# 使用 C++ 析构函数语法 ~Object 有点令人困惑)。如果一个对象覆盖了 Finalize 方法,而不是在超出范围时被 GC 收集,GC 会将其放在终结器队列中。在下一个 GC 周期中,队列中的所有终结器都将运行(在当前实现中的单个线程上),并且从终结对象中回收内存。从这里可以很明显地看出为什么你不想在终结器中进行清理:收集对象需要两个 GC 周期而不是一个,并且有一个线程,所有终结器都在运行,而其他所有线程都被挂起,所以这会损害性能。

因此,如果您没有析构函数,并且您不想将清理工作留给终结器,那么唯一的选择就是手动、确定地清理对象。输入 IDisposable 接口,该接口提供了支持此功能的标准并定义了一个方法 Dispose,您可以在其中放入对象的清理逻辑。当在 finally 块中使用时,此接口提供与析构函数等效的功能。finally 代码中阻塞的原因主​​要是为了支持 IDisposable 接口;这就是为什么 C++ 只使用 try/except 的原因,因为不需要带有析构函数的 finally 块。

于 2012-08-10T05:19:04.593 回答
1

您可以编写一个服务来监视您的应用程序,并在它退出或崩溃时重新启动。

于 2012-08-10T05:21:23.303 回答
0

好的,问题是我的托管 C# ASCOM 驱动程序正被一个非托管 C++ 应用程序使用,该应用程序无法通过将 Connected 属性设置为 false 然后退出来正确断开与驱动程序的连接,所以我试图使用 C# 终结器来捕捉这种情况并停止可能在关闭代码中引用托管对象的不起作用的范围。

解决方法是在终结器/析构函数运行之前使用 appdomain.currentdomain.processexit 事件来运行我的关闭代码。

于 2012-08-10T22:43:02.450 回答
0

实现 IDisposable 对您的 API 来说是一个非常好的主意。
我还会考虑在您的驱动程序和 ASCON 之间编写一个代理服务。
通过任务管理器进行的不安全停止仍然会导致错误停止。

于 2012-08-10T05:59:16.003 回答