【发布时间】: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 方法时,我才坚持。
我想了解发生了什么,以及如何解决它。当然主应用窗体是实例化和可见的,窗口句柄被创建,那么它不应该抛出那个异常......
我在尝试调试真正的问题时发现了这个奇怪的问题,这不是我在这个问题中暴露的问题,但是我认为这个奇怪的问题是我真正问题的原因,所以我很感激这个问题的解决方案.
【问题讨论】:
-
您在辅助线程上运行的任务中使用默认表单实例 (
My.Forms.Main)。你知道每个访问默认值的线程都会创建一个new默认实例吗? -
VB.NET Invoke cannot be called on a control until the window handle has been created, BUT the handle is created 的可能重复项。花了一段时间才找到,但我知道这一定是以前以某种方式问过的。
标签: .net vb.net winforms asynchronous hwnd