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
这是我第一次在应用程序中使用线程。我正在使用 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