在创建窗口句柄之前,无法在控件上调用VB.NET Invoke,但要创建该句柄 [英] VB.NET Invoke cannot be called on a control until the window handle has been created, BUT the handle is created
问题描述
这是我的情况,有2个类,主要形式为Form1:
This is my situation, there are 2 Classes and my main form Form1:
Class1:具有一个doSomethingAndCall(callback)方法,该方法创建一个新线程 Class2:具有动态创建的控件,该控件带有一个触发Class1的按钮.doSomethingAndCall(newCallback)
Class1: has a method doSomethingAndCall(callback) which creates a new thread Class2: has dynamic created controls with a button that fires Class1.doSomethingAndCall(newCallback)
在代码中看起来像这样(它从Class2.Button_Click开始):
in code it looks like this (it starts at Class2.Button_Click):
Class Class1
public shared sub doSomethingAndCallAsync(state as object)
Console.WriteLine(Form1.InvokeRequired) 'output: false
Console.WriteLine(Form1.IsHandleCreated) 'output: false
Form1.Invoke(state.callback) 'throws System.InvalidOperationException
end sub
public shared sub doSomethingAndCall(callback as object)
System.Threading.ThreadPool.QueueUserWorkItem(AddressOf doSomethingAndCallAsync, New With {.callback = callback})
end sub
End Class
Class Class2
Public Delegate Sub doSomethingDelegate()
Public Sub doSomething()
Console.WriteLine("success!")
End Sub
Public Sub Button_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Class1.doSomethingAndCall(New doSomethingDelegate(AddressOf doSomething))
End Sub
End Class
我得到的确切例外是:
在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke
Invoke or BeginInvoke cannot be called on a control until the window handle has been created
我在控制台中看到了
,第4行中的WriteLine向我展示了该表单确实没有创建.所以我添加了这个处理程序,现在它真的很令人困惑:
and as I can see the console.WriteLine in line 4 shows me that the form is realy not created. So I added this handlers, and now it get's really confusing:
Private Sub Form1_HandleCreated(sender As Object, e As System.EventArgs) Handles Me.HandleCreated
Console.WriteLine("Handle created") 'Output: Handle created, when running program
End Sub
Private Sub Form1_HandleDestroyed(sender As Object, e As System.EventArgs) Handles Me.HandleDestroyed
Console.WriteLine("Handle destroyed") 'Will never Output!
End Sub
因此它是创建的,并且从未销毁,但是如果我单击按钮,它仍然不可用? -谁能解释一下发生了什么以及如何正确调用回调,谢谢!
So it's created and never destroyed but if i click the button it's nevertheless not avaible? -Can anyone explain me what is going on and how to call a callback correct, thanks!
推荐答案
My.Forms.Form1
aka的实例.每个线程中的Form1
将有所不同.您需要正确实例的句柄.在您的Form1
上放一个按钮,并添加以下代码:
The instance of My.Forms.Form1
aka. Form1
will be different in each thread. You need a handle to the correct instance. Drop a button onto your Form1
and add the following code:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Threading.Tasks.Task.Factory.StartNew(Sub() Class1.Wrong())
Threading.Tasks.Task.Factory.StartNew(Sub() Class1.Correct(Me))
End Sub
End Class
Public Class Class1
Public Shared Sub Wrong()
Debug.WriteLine(String.Format("(Other thread, wrong) InvokeRequired={0}, IsHandleCreated={1}", Form1.InvokeRequired, Form1.IsHandleCreated))
End Sub
Public Shared Sub Correct(instance As Form1)
Debug.WriteLine(String.Format("(Other thread, correct) InvokeRequired={0}, IsHandleCreated={1}", instance.InvokeRequired, instance.IsHandleCreated))
End Sub
End Class
输出
(其他线程,正确)InvokeRequired = True,IsHandleCreated = True
(Other thread, correct) InvokeRequired=True, IsHandleCreated=True
(其他线程,错误)InvokeRequired = False,IsHandleCreated = False
(Other thread, wrong) InvokeRequired=False, IsHandleCreated=False
这篇关于在创建窗口句柄之前,无法在控件上调用VB.NET Invoke,但要创建该句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!