2012-08-10 68 views
1

我正在寫一個ASCOM望遠鏡驅動程序,我需要保證幾個串口 命令發送到範圍,以防止客戶端應用程序 無法正常斷開連接或崩潰時移動範圍。保證代碼在C#終結器中運行

我嘗試添加一個終結,看起來像這樣

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

它使得在SendSerialPortCommand()方法,然後沒有實際發送 字節出的電線退出,似乎前剛剛辭職鎖定語句。

回購在這裏可以查看

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

終結是driver.cs調用的方法是靜態類常見

有沒有更好的或者更可靠的方式來做到這一點?

回答

4

執行IDisposable接口並在Dispose方法中執行您的工作。

您應該看到這篇文章從格雷格櫸木:Implementing and using the IDisposable interface

取而代之的析構函數,.NET具有通過 實現覆蓋的基礎Object類 定義Finalize方法(終結雖然C#有點混亂的用途C++析構函數語法〜Object )。如果一個對象覆蓋Finalize方法,而不是由GC在超出範圍時收集的 ,則GC將它置於 上的終結器隊列中。在下一個GC循環中,隊列 上的所有終結器都在回收的最終對象中運行(在當前實現中的單個線程上)和 內存中。從 中可以明顯看出爲什麼你不想在終結器中進行清理:它需要兩個GC 週期來收集對象而不是一個,並且有一個單獨的 線程,其中每個其他線程都運行所有終結器 暫停,所以它會損害性能。

因此,如果您沒有破壞程序,並且您不想將 清除到終結器,那麼唯一的選擇是手動確定性地清除對象。輸入IDisposable 接口,該接口提供支持此功能的標準 ,並定義了一個單一方法Dispose,在此處爲對象添加邏輯清理 。當在finally塊中使用時,此接口 爲析構函數提供了等效的功能。 最終在代碼塊中的原因主要是爲了支持IDisposable 接口;這就是爲什麼C++使用簡單的嘗試/除了因爲沒有必要使用 來爲一個帶有析構函數的finally塊。

+0

謝謝,這有助於我更多地瞭解問題,這個問題的根本原因在於,使用驅動程序的應用程序是非託管C++,驅動程序是託管C#所以只有〜Telescope()只會被調用,而我沒有權限強制通過將Connected屬性設置爲false來強制非託管C++應用程序與驅動程序斷開連接。 – user964078 2012-08-10 21:17:30

1

您可以編寫一個監視你的應用程序服務,當它退出或崩潰重新啓動。

0

實現IDisposable對於您的API來說是一個非常好的主意。
我也會考慮寫你的驅動程序和ASCON之間的代理服務。
不安全通過任務管理器停止仍然可能導致糟糕的停止。

0

OK,問題是,我的託管C#ASCOM驅動程序正在使用,不會從驅動器所連接的 屬性設置爲false,然後退出斷開適當的託管C++ 應用程序,所以我試圖用一個C#終結器來捕捉這種情況 ,並停止在關機 代碼中可能引用被管理對象的無效範圍。

解決方法是在運行終結器/析構函數之前使用appdomain.currentdomain.processexit事件運行我的關機 代碼。