2012-01-18 95 views
2

我已經創建了一個C#COM DLL,它本質上是一個增強的進度條,它在新線程上運行System.Windows.Forms.Application.Run()以顯示錶單與對話。要使用VBA使用它在第三方應用程序,你做這樣的事情:C#COM DLL阻止VBA應用程序退出

Set pg = CreateObject("MyNS.MyProgressBar") 
pg.ShowBar() 
. 
. 
pg.Progress = 0.5 
. 
. 
pg.ShutDownBar() 

的問題是,用戶能夠BEFORE pg.ShutDownBar關閉(使用文件 - >退出,或類似)的應用程序()到達了。如果用戶這樣做,pg.ShutDownBar()永遠不會調用,結果是儘管應用程序的窗口是隱藏的,它仍然出現在任務管理器進程中。

所以我的問題是: 是否有某種方法來檢測父應用程序是否已關閉,然後中止在c#中的進度條線程?

我已經嘗試System.Windows.Forms.Application.ThreadExit和System.Windows.Forms.ApplicationExit在啓動對話框線程的主線程,但這些事件似乎不會通過COM訪問對象時引發(儘管他們被稱爲當我在.NET中創建對象)... ...

任何人都可以提供一些建議嗎?

+0

聽起來像一個典型的DoEvents()問題。不要使用它。 – 2012-01-18 04:03:40

+0

沒有任何代碼調用DoEvents()...我試圖不使用Application.Run在單獨的線程上啓動我的對話框,而是在單獨的線程上使用form.ShowDialog(),但隨後對話框基本凍結...不知道爲什麼? – MineR 2012-01-18 04:06:34

+0

如果在應用程序退出事件中將進度條對象設置爲「Nothing」,會發生什麼情況? – 2012-01-18 04:45:44

回答

0

這是COM引用計數工作方式的問題。除非程序調用你的COM包裝器釋放引用(正如M.Babcock所說的那樣,程序需要執行「設置pg = Nothing」的步驟),否則你的進度條將無法正常關閉。

我可以做的唯一建議是設置一個「超時」屬性(默認爲30秒)。然後在進度條中使用後臺線程,該線程會檢查最後一次對「pg.Progess」的調用是否已完成,如果超過了該值,請執行關閉。假設您可以期望大多數VB腳本至少每X秒報告一次進度(其中X是超時值)。

+0

是的!這有效......我將窗口句柄發送到新線程,然後每隔幾秒查看窗口句柄是否仍然有效。如果不是,那麼它關閉。謝謝! – MineR 2012-01-18 05:36:36