长话短说,我在尝试弄清楚如何在使用线程时使用调用和/或委托从单独的类更新用户表单时遇到了困难。我很确定这对于有更多经验的人来说是愚蠢而明显的。我知道可能需要委托,但我所有的努力似乎只有在从主线程调用它时才有效。我在网上查了半天,还是没有明白。
这是一些伪代码作为示例:
此选项有效:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim t1 As New Threading.Thread(AddressOf Count)
t1.IsBackground = True
t1.Start(100)
End Sub
Private Sub Count(ByVal Max As Object)
If TypeOf Max Is Integer Then
Count(CInt(Max))
End If
End Sub
Private Sub SetLabelText(ByVal text As String)
If Label1.InvokeRequired Then
Label1.Invoke(New Action(Of String)(AddressOf SetLabelText), text)
Else
Label1.Text = text
End If
End Sub
Private Sub Count(ByVal Max As Integer)
For i = 1 To Max
SetLabelText(CStr(i))
Threading.Thread.Sleep(200)
Next
End Sub
End Class
而这个(我的 1000 个略有不同的变化的努力之一)却没有。实际上,在这个例子中,我只是尝试将其中一个子程序分离到它自己的类中,但它在其他方面与我可以做到的相同:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim t1 As New Threading.Thread(AddressOf Count)
t1.Start(100)
End Sub
Private Sub Count(ByVal Max As Object)
If TypeOf Max Is Integer Then
Dim class2 As New class2
class2.Count(CInt(Max))
End If
End Sub
Private Delegate Sub SetTextBoxTextInvoker(text As String)
Sub SetLabelText(ByVal text As String)
'or me.label1, form1.label1 or anything else I can try!
If Me.InvokeRequired Then
Me.Invoke(New SetTextBoxTextInvoker(AddressOf SetLabelText), _
text)
Else
Me.Label1.Text = text
End If
End Sub
End Class
Public Class class2
Sub Count(ByVal Max As Integer)
For i = 1 To Max
form1.SetLabelText(CStr(i))
Threading.Thread.Sleep(200)
Next
End Sub
End Class
据我所知,子“SetLabelText”中的 invokerequired 的 if 语句似乎永远不会被触发。我最好的猜测是,在检查 invokerequired 参数时,我没有正确引用用户表单?或者我需要向代表提供其他东西?我只是因为搞乱了我可能会出错的数百万个小变量而感到沮丧。预先感谢您提供的任何帮助,如果您需要更多信息,请告诉我。
我不确定我是否理解您要做什么,但是在您的代码的基础上,您可以使用以下代码安全地设置标签(“线程安全”):
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim t1 As New Threading.Thread(AddressOf Count)
t1.IsBackground = True
t1.Start(100)
End Sub
Private Sub Count(ByVal Max As Object)
If TypeOf Max Is Integer Then
Dim class2 As New Class2
class2.Count(CInt(Max), AddressOf SetLabelText)
End If
End Sub
Private Sub SetLabelText(ByVal text As String)
If Label1.InvokeRequired Then
Label1.Invoke(New SetText(AddressOf SetLabelText), text)
Else
Label1.Text = text
End If
End Sub
End Class
Public Class Class2
Sub Count(ByVal Max As Integer, SetTextMethod As SetText)
For i = 1 To Max
SetTextMethod.Invoke((CStr(i)))
Threading.Thread.Sleep(200)
Next
End Sub
End Class
Public Delegate Sub SetText(text As String)
我创建了一个名为“SetText”的委托;当表单调用类中的 count 函数时,您可以传递引用 SetLabelText 方法的委托实例。在该方法中,您可以通过 Invoke 直接或间接安全地设置标签文本以及委托的新实例。
您绝对不想做的事情是从您的班级引用您的表单(即“form1.SetLabelText(CStr(i))”);随着项目规模的扩大和需求的变化,这可能会造成真正的噩梦!
如果我误解了您的问题或没有正确回答您的问题,请回复。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)