【问题标题】:Unexpected\false positive error: 'Invoke or BeginInvoke cannot be called on a control until the window handle has been created'意外\误报错误:“在创建窗口句柄之前,无法在控件上调用 Invoke 或 BeginInvoke”
【发布时间】:2018-01-31 21:07:11
【问题描述】:

在特定的异步情况下,我收到 System.Reflection.TargetInvocationException 异常,并显示以下错误消息:

在窗口之前不能在控件上调用 Invoke 或 BeginInvoke 句柄已创建

请注意这不是一个重复的问题,下面我将解释原因。我知道错误的含义,但不能/不应该抛出该异常,因为窗口的句柄是在我的代码中创建的。

我开始认为我收到的这条错误消息可能是 .NET Framework 中的一个新错误,我需要有人帮助我澄清代码中的问题是我的错还是不是我的错,并且如何解决这个问题。

我只有这个代表主应用程序表单的类:

Public NotInheritable Class Main : Inherits Form

    Private Async Sub ButtonMirror_Click(sender As Object, e As EventArgs) Handles ButtonMirror.Click

        ' Synchronous.
        ' Dim sucess As Boolean = MirrorUtil.BuildMirror

        ' Asynchronous.
        Dim t As Task(Of Boolean) = Task.Run(Of Boolean)(AddressOf MirrorUtil.BuildMirror)
        Dim sucess As Boolean = Await t

    End Sub

End Class

请注意,事件处理程序指定了 Async 关键字。

这就是BuildMirror 方法

Friend NotInheritable Class MirrorUtil

    Friend Shared Function BuildMirror() As Boolean
        My.Forms.Main.Invoke(Sub() My.Forms.Main.Visible = False)
    End Function

End Class

问题出在 BuildMirror 方法的块内,只有当我像在上面的代码中那样异步调用它时才会发生,Main.Invoke() 方法会抛出提到的异常,并且如果我执行调用到Main.IsHandleCreated 它出乎意料地返回False! ...只有当我异步调用 BuildMirror 方法时,我才坚持。

我想了解发生了什么,以及如何解决它。当然主应用窗体是实例化和可见的,窗口句柄被创建,那么它不应该抛出那个异常......

我在尝试调试真正的问题时发现了这个奇怪的问题,这不是我在这个问题中暴露的问题,但是我认为这个奇怪的问题是我真正问题的原因,所以我很感激这个问题的解决方案.

【问题讨论】:

标签: .net vb.net winforms asynchronous hwnd


【解决方案1】:

考虑有关问题的以下事实:

  1. 当您在另一个线程中调用My.Forms.Main 时,您得到的表单不是您在主线程中创建和显示的表单。这是Main 的一个新实例。但是如果你在主线程中调用它,它就是创建它的句柄的现有实例。 (My.Forms.Something 将返回主窗体的现有实例,而对于其他窗体,创建一个新实例并将其缓存并使用它。)

  2. 调用Invoke方法会抛出异常,如果没有创建表单句柄,显示后会创建表单句柄。

当您在另一个线程中调用My.Forms.Main.Invoke(Sub() My.Forms.Main.Visible = False) 时,My.Forms.Main 将是一个新实例,并且它的句柄未创建,因此在其上调用Invoke 将导致您收到的异常。

【讨论】:

    【解决方案2】:

    我会简化这一点。你不需要其他类。

    Public NotInheritable Class Main : Inherits Form
    
        Private Async Sub ButtonMirror_Click(sender As Object, e As EventArgs) Handles ButtonMirror.Click
    
            Me.Invoke(Sub() Me.Visible = False)
    
        End Sub
    
    End Class
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-22
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 2023-01-10
      • 2014-10-27
      • 1970-01-01
      相关资源
      最近更新 更多