Control.Invoke 使用 VB.NET 和 CF3.5 时出现问题

Trouble with Control.Invoke using VB.NET and CF3.5

这是我第一次在应用程序中使用线程。我正在使用 VB.NET、VS2008 和 CF3.5

我做了一个小测试项目来尝试了解线程的工作原理,尤其是在尝试访问另一个线程中的 UI 控件时。我的表单只是一个显示 "Start" 的按钮,按下时应使用 "Stop" 来回切换。

这是我的测试项目的代码,是我根据我在网上找到的几个示例放在一起的。

Public Class Form1

Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
    Dim myThread As New System.Threading.Thread(AddressOf ChangeText)
    myThread.Start()
End Sub

Private Sub ChangeText() 
    If button1.InvokeRequired Then
        Me.Invoke(New Threading.WaitCallback(AddressOf ChangeText))
    Else
        If button1.Text = "Start" Then button1.Text = "Stop"
        If button1.Text = "Stop" Then button1.Text = "Start"
    End If
End Sub

它的构建和部署都很好,但是只要我单击按钮,我就会在调用上得到一个 "ArgumentException is unhandled"。

我做错了什么?

我重写了 Invoke 以仅使用 lambda 调用子例程。此外,我从 Invoke 更改为 BeginInvoke,因为您无需等待它完成。

Public Class Form1

    Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
        Dim myThread As New System.Threading.Thread(AddressOf ChangeText)
        myThread.Start()
    End Sub

    Private Sub ChangeText()
        If button1.InvokeRequired Then
            Me.BeginInvoke(Sub() ChangeText())
        Else
            If button1.Text = "Start" Then button1.Text = "Stop"
            If button1.Text = "Stop" Then button1.Text = "Start"
        End If
    End Sub

End Class

[编辑]

我修改了代码以使用委托而不是 lamdb。

Public Class Form1

        Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
                Dim myThread As New System.Threading.Thread(AddressOf ChangeText)
                myThread.Start()
        End Sub

        Private Sub ChangeText()
                If button1.InvokeRequired Then
                        Me.BeginInvoke(New Threading.ThreadStart(AddressOf ChangeText)))
                Else
                        If button1.Text = "Start" Then button1.Text = "Stop"
                        If button1.Text = "Stop" Then button1.Text = "Start"
                End If
        End Sub

End Class   

这是最终有效的代码:

Public Class Form1

Delegate Sub TextDelegte()
Private myTextSub As TextDelegte = New TextDelegte(AddressOf ChangeText)

Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click

    Dim myThread As New System.Threading.Thread(AddressOf ChangeText)
    myThread.Start()
End Sub

Private Sub ChangeText()
    If button1.InvokeRequired Then
        Invoke(myTextSub)
        System.Threading.Thread.Sleep(100)
    Else
        If button1.Text = "Start" Then
            button1.Text = "Stop"
        ElseIf button1.Text = "Stop" Then
            button1.Text = "Start"
        End If
    End If
End Sub

End Class