gpt4 book ai didi

multithreading - 从新线程处理 ExcelDnaUtil.Application

转载 作者:行者123 更新时间:2023-12-03 13:00:14 32 4
gpt4 key购买 nike

我正在使用 ExcelDNA 开发 XLL。

在其中,我有一个位于 DLL 中的表单,我将“ExcelDnaUtil.Application”作为成员传递给该表单,以促进表单与运行 XLL 的 Excel 实例之间的交互。

如果我使用以下方法在主线程中启动表单:

form1.show()

当我关闭表单然后关闭 Excel 时,Process Explorer 显示 Excel 进程已正确处理。

如果我使用新线程启动表单:
Dim workerThread As Thread
workerThread = New Thread(Sub() form1.showdialog())
workerThread.Start()

当我关闭表单然后关闭 Excel 时,该过程仍保留在 Process Explorer 中。我一直小心不要在任何代码行中使用两个小数点,并在关闭表单时将接口(interface)成员设置为“无”。我没有使用“ReleaseCOMObject”,因为其他文章表明这​​是不好的做法。

问题:如何从单独的线程中正确处理 Excel 进程?

最佳答案

使 COM 的东西正确跨线程是不可能的。

您永远不应该从另一个线程与 Excel COM 对象模型对话。如果您遵循这个简单的规则,您就不必担心两个点,不必将任何内容设置为 Nothing,也不必调用任何 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

关于multithreading - 从新线程处理 ExcelDnaUtil.Application,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25434845/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com