VB.net正在从其他线程更新标签



我可能已经阅读并尝试了一百种不同的方法来实现这一点,但我再也无法忍受了。我是多线程的新手,通常会让UI处理代码。随着程序的发展,我发现了自己的错误。现在我有了类和一个不会滞后/冻结主UI的线程。

在这个类中,我试图更新主表单上的标签

相关代码如下:

主表单上有一个名为UpdateLabel 的标签

主窗体上的一个按钮:

Private Sub btnStartMenu_Click(sender As Object, e As EventArgs) Handles 
btnStartMenu.Click
Call New Action(AddressOf setupthread1).BeginInvoke(Nothing, Nothing)
End Sub 'creates a new thread which runs great, not freezing the UI!

Private Sub setupthread1()    'this code is still on the main form
'all of the label updates work fine from here.
StartMenu_Folders.startMenuFolders()  'This is the class that gets called 
'from the main form
Public Class StartMenu_Folders
Public Shared Sub startMenuFolders()
frmMenu.UpdateLabel(frmMenu.lblLogoff, "...Updating Label text")    'this code is probably incorrect? Though the updatelabel DOES get 
'successfully called

'This next part is back on the main form.
Public Sub UpdateLabel(ByVal lblLogoff As Label, ByVal Value As String)
If lblLogoff.InvokeRequired Then
Dim dlg As New UpdateLabelDel(AddressOf UpdateLabel)
dlg.Invoke(lblLogoff, Value)
Else
lblLogoff.Text = Value
End If
End Sub

如果有任何帮助,我们将不胜感激,这可能是你们一位资深程序员2秒钟的解释。

在这一点上,看起来线程运行得很完美,没有冻结,但标签没有更新。非常感谢。我真的很感激!

==========================根据提供的信息将EDIT更新为Code。

来自像你这样的观众提示阅读彩虹音乐

'This is all on Main form 'frmMenu'
'Improved way of starting the class in a new thread
Private Sub btnStartMenu_Click(sender As Object, e As EventArgs) Handles btnStartMenu.Click
Dim t As Task = Task.Run(Sub()
StartMenu_Folders.startMenuFolders()
End Sub)
End Sub
Public Delegate Sub UpdateLabelInvoker(ByVal text As String)
Public Sub UpdateLabel(ByVal text As String)
If Me.lblLogoff.InvokeRequired Then
Me.lblLogoff.Invoke(New UpdateLabelInvoker(AddressOf UpdateLabel), _
text)
MsgBox("invoked")
Else
Me.lblLogoff.Text = text
MsgBox("DIDNT invoke")
End If
End Sub
'This is all in the class
Public Class StartMenu_Folders
Public Shared Sub startMenuFolders()
frmMenu.UpdateLabel("testtestest")
End Sub
End Class
'This code is still creating a separate instance of frmMenu I believe.
'I'm not sure how to target the right thread to update the label. 
'I've tried me.UpdateLabel("testtesttest") to no avail.

如果有人知道怎么做,那就太好了!其他一切都进展顺利。很遗憾,从另一个线程更新表单上的标签是我在这个项目上工作的几个月里所经历的最艰难的一环。

您不会在委托上调用Invoke并传递Label。您在Label上调用Invoke并传递委托:

lblLogoff.Invoke(dlg, Value)

请参阅我的解释和示例。

编辑:

好吧,我想这次我已经掌握了。此:

Public Class StartMenu_Folders
Public Shared Sub startMenuFolders()
frmMenu.UpdateLabel(frmMenu.lblLogoff, "...Updating Label text")    'this code is probably incorrect? Though the updatelabel DOES get 
'successfully called

变为:

Public Class StartMenu_Folders
Public Shared Sub startMenuFolders(menuForm As frmMenu)
menuForm.UpdateLabel("...Updating Label text")

此:

StartMenu_Folders.startMenuFolders()

变为:

StartMenu_Folders.startMenuFolders(Me)

此:

Public Sub UpdateLabel(ByVal lblLogoff As Label, ByVal Value As String)
If lblLogoff.InvokeRequired Then
Dim dlg As New UpdateLabelDel(AddressOf UpdateLabel)
dlg.Invoke(lblLogoff, Value)
Else
lblLogoff.Text = Value
End If
End Sub

变为:

Public Sub UpdateLabel(ByVal Value As String)
If lblLogoff.InvokeRequired Then
Dim dlg As New UpdateLabelDel(AddressOf UpdateLabel)
lblLogoff.Invoke(dlg, Value)
Else
lblLogoff.Text = Value
End If
End Sub

以后,请不要在同一个块中发布来自两个不同类的代码,因为这在这里造成了混乱。如果您有两个类,那么将它们的代码发布在两个不同的块中。

最新更新