2

我有一个引用 VB6 旧版 DLL 的 .NET 应用程序。旧版 DLL 有一个带有公共方法的类。在这个公共方法中,它试图按名称查找现有表单,或者如果它不存在则创建它:

Set objForm = GetForm(strFormName)

If objForm Is Nothing Then

    'Creates a new instance of the form
    Set objForm = VB.Forms.Add(strFormName)

End If

...在哪里GetForm

Private Function GetForm(ByVal strFormName As String) As Form

    Dim objForm As Form

    For Each objForm In VB.Forms
        If objForm.Name = strFormName Then
            Set GetForm = objForm
            Exit Function
        End If
    Next

    Set GetForm = Nothing

End Function

它在这一行引发了一个错误:

Set objForm = VB.Forms.Add(strFormName)

错误是:

Automation error
The object invoked has disconnected from its clients.   
Error#-2147417848(80010108)

请注意,这strFormName是一个有效的表单名称,并且此公共方法调用几乎一直有效。它只是偶尔会引发此错误。

我想知道是什么导致了这个错误,或者我还能做些什么来进一步追踪它?

4

2 回答 2

6

@Dabblernl 链接的知识库文章与此问题非常相关。VB.Forms 集合正是这样一个不合格的参考。它就像一个全局变量,您可以在 VB6 代码中的任何地方使用 VB.Forms,而无需提供对象引用。

在底层,VB6 运行时会在您第一次创建表单时创建 Forms 集合并存储此集合对象,以便将来对 VB.Forms 的引用使用完全相同的集合。错误代码的意思是您在该集合被销毁后使用它

何时发生这种情况还不是很清楚,这都是 VB6 运行时支持库的内部管道。但通常情况下,VB6 应用程序会在最后一个表单被卸载时终止。您的情况不同的是,您的进程的生命周期不再由 VB6 运行时控制。.NET 现在控制它。

因此,据此推断,VB6 运行时很有可能已决定不再需要 Forms 集合并将其销毁,并且您的 .NET 代码稍后可能会创建一个新的 Form,从而触发错误。

如果这完全准确,那么您需要采取对策来防止这种情况发生。一种可能的方法是确保始终存在至少一个 VB6 表单以保持集合有效。它不必是可见的。

于 2013-02-21T03:14:15.197 回答
1

如果问题是间歇性的并且很少如 OP 中所述,重试可能会解决它:

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Sub SomeProcedure()
Dim attempts As Integer
On Error Goto ErrHandler

    Set objForm = GetForm(strFormName)
    If objForm Is Nothing Then

        'Creates a new instance of the form
        Set objForm = VB.Forms.Add(strFormName)

    End If

ErrHandler:
    If Err.Number = -2147417848 Then
        attempts = attempts + 1
        If attempts < 10 Then
            Err.Clear
            Sleep 55
            Debug.Print "Automation error. Retry attempt: " & attempts
            Resume
        End If
    End If
    If Err.Number <> 0 Then 'this should run after the 10th failed attempt
        MsgBox Err.Message
        Err.Clear
    End If
End Sub

它没有解决问题,但它可能会阻止您的应用程序因此而崩溃......

于 2013-02-16T16:40:08.633 回答