2011-08-12 102 views
2

我有,我用它來查詢該傳感器的一些硬件傳感器封閉源代碼API。 API來自我通過C#interop使用的DLL。 API的功能被阻止。他們通常會返回錯誤值,但在某些情況下,他們不會返回。看門狗阻止函數調用

我需要能夠檢測到這種情況,在這種情況下殺死被阻塞的線程。這怎麼可以在C#中完成?

他們正在上通過一個BackgroundWorker創建調用線程。我正在尋找一個簡單的看門狗,用於阻止函數調用,在調用函數之前我可以設置它,並在我回來時重置。它應該坐在那裏等我回來。如果我不這樣做,使1)API再次釋放了,沒有我的應用程序的線程仍然賴在那裏做什麼應該它最終返回和2)我可以像其他恢復措施應當殺死線程重新初始化API以繼續使用它。

回答

6

一個辦法是,建立一個System.Threading.Timer API調用之前一定的超時時間間隔之後觸發,則調用完成後處置定時器。如果Timer觸發,它將觸發一個ThreadPool線程,然後您可以採取適當的操作來殺死有問題的線程。

請注意,你需要的P/Invoke對Win32 API TerminateThread,因爲.NET的Thread.Abort的(),如果你擋在非託管代碼將無法正常工作。

另外請注意,這是非常不太可能你的過程將是處於安全狀態後強行殺死一個線程,爲終止線程可能擁有的同步對象,可能是中間變異共用存儲器狀態,或者任何其他這樣的關鍵操作。由於終止它,其他線程可能會掛起,進程可能會崩潰,數據可能會損壞,狗和貓可能會一起生活;沒有辦法確定會發生什麼,但機會會很糟糕。如果可能的話,最安全的方法是將API的使用隔離到一個獨立的進程中,通過一些遠程通道與之通信。然後你可以按需殺死外部進程,因爲殺死一個進程比殺死一個線程安全得多。

+0

很好的答案。除了住在一起的貓和狗,當你殺死線程時,內存將會泄漏。我喜歡你有一個可以被殺死的單獨程序的建議。這種清理方式更加自動化。 –

+0

+1:同意。單獨的流程是最好的選擇。它很糟糕,但有時候生活也是如此。 –

+0

單獨的過程理念確實很好。這也將使我無法構建用於x86的整個託管應用程序,因爲我只有該非託管DLL的32位版本。 (只是看看是否還有其他想法。) – ygoe