我可能已经阅读并尝试了一百种不同的方法来执行此操作,但是我不能再忍受它或将头缠在它上面了。我是多线程的新手,通常使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.
如果有人知道该怎么做,那就太好了!其他所有东西都在畅快地工作。很遗憾,从另一个线程更新表单上的标签是在我从事该程序的几个月中,我不得不经历的最困难的工作。
答案 0 :(得分:3)
您不会在代理上致电Invoke
并传递Label
。您在Invoke
上呼叫Label
并传递委托:
lblLogoff.Invoke(dlg, Value)
请参阅我的说明和示例here。
编辑:
好的,我想这次可以解决了。这个:
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
将来,请不要在同一块中发布来自两个不同类的代码,因为这会在此处造成混乱。如果您有两个类,则将它们中的代码发布到两个不同的块中。