我收到"Invoke or BeginInvoke cannot be called on a control until the window handle has been created"错误



我有 3 个函数:

  • wait((:在处理时显示加载表单。
  • runwait((:使表单加载在线程中工作。
  • 停止等待:在处理完成后停止加载。

问题:函数工作正常,但有时以某些形式显示此错误"在创建窗口句柄之前无法在控件上调用 Invoke 或 BeginInvoke">

Public Sub wait()
ld = New Wform
Application.Run(ld)
End Sub
Public Sub runwait()
Dim th As System.Threading.Thread = New Threading.Thread(AddressOf wait)
th.SetApartmentState(ApartmentState.STA)
th.Start()
End Sub
Public Sub stopwait()
ld.BeginInvoke(New Action(Sub() ld.Dispose()))
End Sub

当然,这些选项之一应该会让您满意

1.这很简单。只需显示表格并处理它。它不是模式的,它在原始 UI 线程上运行。wait不是阻塞调用,因此不需要任何其他线程。当窗口关闭时,一段时间后自动调用"释放它"。如果您在关闭后尝试处置,则有可能它已经被处置,您将获得您得到的异常。请参阅底部处理这种情况的stopwait方法。

Public Sub wait()
ld = New Wform()
ld.Show()
End Sub

2.这是阻塞。显示对话框窗口会阻止其他代码运行。 如果要释放,则需要调用stopwait,因为对话框窗口在关闭时不会自动释放。在表单关闭之前,您无法使用呼叫表单。

Public Sub wait()
ld = New Wform()
ld.ShowDialog()
End Sub

3.当从非 UI 线程调用wait时。(1. 和2.都可以使用此方法确保 UI 线程安全。当 UI 应用程序中存在多个线程时,通常最好使用 InvokeRequired/Invoke 模式。

Public Sub wait()
If Me.InvokeRequired Then
Me.Invoke(New Action(AddressOf wait))
Else
ld = New Wform()
ld.Show()
End If
End Sub

在大多数情况下,ShowDialogShow应该满足您尝试执行的操作:阻止或不阻止。

在所有情况下,stopwait看起来都一样。

Public Sub stopwait()
If ld IsNot Nothing Then
If ld.InvokeRequired Then
ld.Invoke(New Action(AddressOf stopwait))
Else
If Not ld.IsDisposed Then ld.Dispose()
End If
End If
End Sub

相关内容

  • 没有找到相关文章

最新更新