Sup Guys,
我在我的frmMain类上有一个函数,它会在调用后将我的控件更新为其他东西。当我在立即窗口上键入“?Label1.Text”时,文本属性IS更新,但当我去检查表单时,没有任何反应。代码就像这样
Public Sub UpdateUI()
If (Me.InvokeRequired = True) Then
Invoke(New MethodInvoker(AddressOf UpdateUI))
End If
Label1.Text = "ITS NOT WORKING =\"
End Sub
在我的bgWorker类上:
Private threadUpd As New Threading.Thread(AddressOf Updater)
Private _active as Boolean
Public Sub New()
_active = True
threadLimpar.IsBackground = True
threadLimpar.Start()
End Sub
Public Sub Updater()
Do
If (_active = False) Then
Try
Thread.Sleep(Timeout.Infinite)
Catch ex As ThreadInterruptedException
End Try
Else
if(condition...) then
frmMain.UpdateUI
End if
Loop
End Sub
答案 0 :(得分:3)
这是VB.NET中的一个经典陷阱,每个人在开始使用线程时至少会陷入其中一次:
frmMain.UpdateUI
现在我们无法看到“frmMain”究竟是什么意思。但是您发布此问题的事实表明frmMain是您的主要表单类的名称。不是类中存储对主窗体的引用的字段的名称。
这不起作用。 VB.NET编译器生成的变量允许您作为类引用,就好像它是一个变量具有<ThreadStatic>
语义。换句话说,每个线程都将创建自己的表单实例。您可以按照以下方式对其进行排序:
frmMain.UpdateUI
frmMain.Show
但是你会看到窗口的“幽灵”,否则它就像死角一样死了,因为它创建的线程并没有引发消息循环。
您需要对表单进行真正的引用。如果Updater是表单类的方法,那可能是“我”。如果不是,Application.OpenForms可以提供它。最好的办法是通过构造函数为包含Updater的类提供对表单的引用。
答案 1 :(得分:2)
如果InvokeRequired返回true,您可能应该终止该函数,但无论如何都要设置标签文本。以下是您可能会做的事情:
Public Sub UpdateUI()
If (Me.InvokeRequired = True) Then
Invoke(New MethodInvoker(AddressOf UpdateUI))
Else
Label1.Text = "ITS NOT WORKING =\"
End If
End Sub
答案 2 :(得分:1)
我想你想要以下内容:
Public Sub UpdateUI()
If (Me.InvokeRequired) Then
BeginInvoke(New MethodInvoker(AddressOf UpdateUI))
Else
Label1.Text = "ITS NOT WORKING =\"
End If
End Sub