在创建窗口句柄之前,不能对控件调用VB.NET Invoke,但创建了句柄



这是我的情况,有2个类和我的主要形式Form1:

Class1:有一个方法doSomethingAndCall(callback),它创建一个新线程Class2:有一个动态创建的控件,带有一个触发Class1.doSomethingAndCall(newCallback)的按钮

在代码中,它看起来是这样的(它从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

正如我所看到的控制台。第4行的WriteLine向我展示了表单实际上并没有创建。所以我添加了这个处理程序,现在它变得非常令人困惑:

 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

所以它是被创建的,从未被破坏过,但如果我点击按钮,它仍然不可用-有人能向我解释一下发生了什么以及如何正确调用回调吗,谢谢!

My.Forms.Form1的实例,也就是。CCD_ 2在每个线程中将是不同的。您需要一个正确实例的句柄。将一个按钮放在Form1上,然后添加以下代码:

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

(其他线程,错误)InvokeRequired=False,IsHandleCreated=False

相关内容

最新更新