保证代码在C#终结器中运行

时间:2012-08-10 05:13:56

标签: c# serial-port destructor finalizer ascom

我正在编写一个ASCOM望远镜驱动程序,我需要保证一些串口 命令被发送到范围以阻止范围在客户端应用程序时移动 无法正常断开连接或崩溃。

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

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

它使它成为SendSerialPortCommand()方法,然后退出而不实际发送 线路上的字节数似乎在锁定语句之前退出。

repo可以在这里查看

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

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

有更好或更可靠的方法来实现这一目标吗?

4 个答案:

答案 0 :(得分:4)

实施IDisposable界面并在Dispose方法中完成您的工作。

你应该看到Greg Beech的这篇文章:Implementing and using the IDisposable interface

  

而不是析构函数,.NET有终结器,它由实现   覆盖基础Object类上定义的Finalize方法   (尽管C#有点令人困惑地使用了C ++析构函数语法~Object   为了这)。如果一个对象覆盖了Finalize方法,那么而不是   当GC超出范围时由GC收集,GC将其置于其上   终结队列。在下一个GC循环中,队列中的所有终结器   运行(在当前实现中的单个线程上)和   回收的最终对象的记忆。这很明显   这就是为什么你不想在终结器中进行清理:它需要两个GC   收集对象的周期而不是一个,并且只有一个   每个其他线程运行所有终结器的线程   暂停,所以这会伤害表现。

     

所以,如果你没有析构函数,那么你不想离开   清理到终结器,然后唯一的选择是手动,   确定性地,清理对象。输入IDisposable   接口,提供支持此功能的标准   并定义一个方法,Dispose,放在清理中   对象的逻辑。在finally块中使用时,此接口   提供与析构函数相同的功能。的原因   最后代码中的块主要是为了支持IDisposable   接口;这就是C ++使用简单的try / except的原因,因为没有必要   对于带有析构函数的finally块。

答案 1 :(得分:1)

您可以编写一个服务来监视您的应用程序以及它何时退出或崩溃重启。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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