几天来我一直试图理解这一点,并想知道这是我遗漏的简单事情还是完全错误的事情。
例子:
两个文件 - TestClass.vb、myForm.vb
TestClass.vb 如下所示:
Imports System.Threading
Public Class TestClass
Private myClassThread As New Thread(AddressOf StartMyClassThread)
Public Sub Start()
myClassThread.Start()
End Sub
Private Sub StartMyClassThread()
myForm.Msg("Testing Message")
End Sub
End Class
myForm.vb 是一个基本表单,带有一个列表框控件和一个分别命名为 Output 和 StartButton 的按钮控件。
表单背后的代码如下:
Public Class myForm
Private classEntity As New TestClass
Private Sub StartButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles StartButton.Click
Msg("Start Button Pressed")
classEntity.Start()
End Sub
Delegate Sub MsgCallBack(ByVal mesg As String)
Public Sub Msg(ByVal mesg As String)
If Output.InvokeRequired Then
MsgBox("Invoked")
Dim d As New MsgCallBack(AddressOf Msg)
Invoke(d, New Object() {mesg})
Else
MsgBox("Not Invoked")
mesg.Trim()
Output.Items.Add(mesg)
End If
End Sub
End Class
结果:
应用程序运行,没有错误或异常。
显示的是列表框和开始按钮。
我按下开始按钮,一个 msgbox 按预期显示“未调用”,点击确定后,该 msgbox“按下开始按钮”被添加到输出列表框控件中。
紧接着消息框再次弹出并显示“未调用”。我期待“调用”,因为一个单独的线程正在尝试使用输出列表框控件。
当然,这会导致尝试使用 Output.Items.Add,这会导致没有可见结果,因为不允许线程直接更新 UI 控件。
我一定读过几本不同页的小书,试图彻底了解陷阱和方法,但我觉得我可能陷入了很多人可能会做的陷阱。
以我目前的理解和知识,我无法摆脱那个陷阱,希望得到任何意见或建议。
亲切的问候,
莱克斯
最佳答案
这里的问题是您正在调用函数 Msg
不是在 myForm 的实例上,而是作为 myForm 类的共享函数。
在 TestClass
中更改您的代码加上
Public FormInstance as myForm
然后更换
myForm.Msg("Testing Message")
和
FormInstance.Msg("Testing Message")
然后在
StartButton_Click
添加行classEntity.FormInstance = Me
你会得到预期的结果。
关于VB.NET 多线程。从单独的类文件中的类调用 UI 控件的 invoke,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5990649/