2012-01-18 97 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