Multithreading 从新线程处理ExcelDnaUtil.应用程序
我正在用ExcelDNA开发一个XLL 在其中,我有一个位于DLL中的表单,我将“ExcelDnaUtil.Application”作为成员传递给它,以促进表单与运行XLL的Excel实例之间的交互 如果我使用以下命令在主线程中启动表单:Multithreading 从新线程处理ExcelDnaUtil.应用程序,multithreading,excel,vb.net-2010,excel-dna,Multithreading,Excel,Vb.net 2010,Excel Dna,我正在用ExcelDNA开发一个XLL 在其中,我有一个位于DLL中的表单,我将“ExcelDnaUtil.Application”作为成员传递给它,以促进表单与运行XLL的Excel实例之间的交互 如果我使用以下命令在主线程中启动表单: form1.show() 当我关闭表单然后关闭Excel时,Process Explorer会显示Excel进程已正确处理 如果我使用新线程启动表单: Dim workerThread As Thread workerThread = New Thread(
form1.show()
当我关闭表单然后关闭Excel时,Process Explorer会显示Excel进程已正确处理
如果我使用新线程启动表单:
Dim workerThread As Thread
workerThread = New Thread(Sub() form1.showdialog())
workerThread.Start()
当我关闭表单,然后关闭Excel时,流程将保留在process Explorer中。我一直很小心,没有在任何代码行中使用两个小数点,并在关闭表单时将接口成员设置为“nothing”。我没有使用“ReleaseCOMObject”,因为其他文章已经指出这是一种不好的做法
问题:如何从单独的线程正确地处理Excel进程?跨线程处理COM内容是不可能的 永远不要从另一个线程与Excel COM对象模型对话。如果你遵循这条简单的规则,你就永远不必担心两点,永远不必将任何东西设置为零,也不必调用任何ReleaseComObject hack。Excel将很好地关闭 由于Excel是单线程的(实际上是因为Excel COM对象模型位于单线程单元中),因此使用另一个线程与Excel对话不会对性能产生任何好处—在内部,所有这些都会被封送到主线程 如果您敢于从另一个线程与Excel对话,那么任何COM调用都可能在任何时候失败。这是因为Excel仍处于“活动”状态,可能会进入“对象模型已挂起”状态,导致所有COM调用失败(甚至COM消息筛选器也无法捕获错误)。Excel什么时候会进入如此顽固的模式?例如,当用户做一些疯狂的事情时,比如单击鼠标按钮 那么,在您对另一个线程完成一些工作后,如何调用Excel?Excel DNA有一个助手,当Excel处于COM调用安全的模式时,它将安排在主线程上完成的工作。您只需使用包含要完成的工作的委托调用
ExcelAsyncUtil.QueueAsMacro(…)
。这个调用可以在任何时候从任何线程进行,但是代码只有在准备就绪时才会运行
一个有点笨拙的例子是:
Public Module MyFunctions
Dim workerThread As Thread
Public Function OverwriteMe() As Object
Dim caller = ExcelDnaUtil.Application.Caller
workerThread = New Thread( _
Sub()
Thread.Sleep(5000)
ExcelAsyncUtil.QueueAsMacro( _
Sub()
caller.Value = "Done!!!"
End Sub)
End Sub)
workerThread.Start()
Return "Doing it..."
End Function
End Module