简体   繁体   English

C#COM DLL阻止VBA应用程序退出

[英]C# COM DLL is preventing VBA application from exiting

I have created a C# COM DLL which is essentially an enhanced progress bar that runs a System.Windows.Forms.Application.Run() on a new thread to show the form with the dialog. 我创建了一个C#COM DLL,它本质上是一个增强的进度条,它在新线程上运行System.Windows.Forms.Application.Run()以显示带有对话框的表单。 To use it in a third party application using VBA you do something like: 要在使用VBA的第三方应用程序中使用它,您需要执行以下操作:

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

The problem is that the user is able to close the application (using File->Quit, or similar) BEFORE pg.ShutDownBar() is reached. 问题是用户可以在到达pg.ShutDownBar()之前关闭应用程序(使用File-> Quit或类似方法)。 If the user does this, pg.ShutDownBar() is never called and the result is that although the window of the application is hidden, it still appears in task manager processes. 如果用户执行此操作,则永远不会调用pg.ShutDownBar(),结果是尽管隐藏了应用程序的窗口,但它仍出现在任务管理器进程中。

So my question is: Is there some way to detect whether the parent application has shut down and then abort the thread for the progress bar in c#? 所以我的问题是:是否有某种方法可以检测父应用程序是否已关闭,然后中止c#中进度条的线程?

I have tried System.Windows.Forms.Application.ThreadExit and System.Windows.Forms.ApplicationExit on the main thread that starts the dialog thread, but these events appear not to be raised when accessing the object through COM (though they are called when I create the object in .NET).... 我已经在启动对话框线程的主线程上尝试过System.Windows.Forms.Application.ThreadExit和System.Windows.Forms.ApplicationExit,但是通过COM访问对象时似乎不会引发这些事件(尽管在我在.NET中创建对象)。

Can anyone provide some advice? 谁能提供一些建议?

This is problem with the way COM reference counting works. 这是COM引用计数工作方式的问题。 Unless the program calling into your COM wrapper releases the reference (as M. Babcock suggested that would require the program to get to a step where you do "set pg = Nothing"), your progress bar will not get properly shut down. 除非调用COM包装程序的程序释放了引用(如M. Babcock所建议,将要求该程序进入执行“ set pg = Nothing”的步骤),否则进度条将无法正确关闭。

The only suggestion I can make is to setup a "timeout" property (and default it to say 30 seconds). 我可以提出的唯一建议是设置“超时”属性(默认为30秒)。 Then use a background thread in the progress bar, that checks how long ago the last call to "pg.Progess" was made and if it's > timeout value, do a shutdown. 然后在进度栏中使用一个后台线程,该线程检查上一次对“ pg.Progess”的调用是在多长时间之前进行的,如果它的超时值大于超时值,请执行关机。 This is assuming you can expect most VB scripts to report progress at least every X seconds (where X is the timeout value). 这是假设您可以预期大多数VB脚本至少每X秒报告一次进度(其中X是超时值)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM