0

伙计们,

我的 frmMain 类上有一个函数,它将在调用后将我的控件更新为其他内容。当我在即时窗口上键入“?Label1.Text”时,文本属性已更新,但是当我检查表单时,什么也没发生。代码是这样的

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
4

3 回答 3

3

这是 VB.NET 中的一个经典陷阱,每个人在开始使用线程时至少会陷入一次:

frmMain.UpdateUI

现在我们看不到“frmMain”的确切含义。但是您发布此问题的事实表明 frmMain 是您的主要表单类的名称。不是类中存储对主表单的引用的字段的名称。

那是行不通的。VB.NET 编译器生成的变量允许您作为类引用,就好像它是一个变量一样具有<ThreadStatic>语义。换句话说,每个线程都会创建自己的表单实例。当你这样写时,你可以看到它:

frmMain.UpdateUI
frmMain.Show

但是您会看到窗口的“幽灵”,否则它就像门钉一样死了,因为创建它的线程没有泵送消息循环。

您将需要对表单的真实引用。如果 Updater 是表单类的方法,那可能是“我”。如果不是,Application.OpenForms 可以提供它。最好的办法是通过其构造函数为包含 Updater 的类提供对表单的引用。

于 2010-01-02T23:14:58.067 回答
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
于 2010-01-02T22:48:56.160 回答
1

我认为您想要以下内容:

Public Sub UpdateUI()
    If (Me.InvokeRequired) Then
        BeginInvoke(New MethodInvoker(AddressOf UpdateUI))
    Else
        Label1.Text = "ITS NOT WORKING =\"
    End If
End Sub
于 2010-01-02T22:49:28.633 回答