VB.NET Invoke cannot be called on a control until the window handle has been created, BUT the handle is created

只愿长相守 提交于 2019-12-10 10:14:01

问题


This is my situation, there are 2 Classes and my main form Form1:

Class1: has a method doSomethingAndCall(callback) which creates a new thread Class2: has dynamic created controls with a button that fires Class1.doSomethingAndCall(newCallback)

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

The exact exception I get is:

Invoke or BeginInvoke cannot be called on a control until the window handle has been created

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!


回答1:


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

Output

(Other thread, correct) InvokeRequired=True, IsHandleCreated=True

(Other thread, wrong) InvokeRequired=False, IsHandleCreated=False



来源:https://stackoverflow.com/questions/25644824/vb-net-invoke-cannot-be-called-on-a-control-until-the-window-handle-has-been-cre

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!