Vb.net 更改控件';通过委托创建属性
首先,如果我的英语不好,请原谅,我不是以英语为母语的人 我对编程相当陌生,我正在尝试自学VB.NET 我在试图了解代表时遇到了一个问题。(见下面的代码) 我试图完成的是通过线程更新指定控件的文本属性。但是,一旦启动线程,就会出现ArgumentException错误。我完全不知道怎么了。有人知道我做错了什么吗Vb.net 更改控件';通过委托创建属性,vb.net,Vb.net,首先,如果我的英语不好,请原谅,我不是以英语为母语的人 我对编程相当陌生,我正在尝试自学VB.NET 我在试图了解代表时遇到了一个问题。(见下面的代码) 我试图完成的是通过线程更新指定控件的文本属性。但是,一旦启动线程,就会出现ArgumentException错误。我完全不知道怎么了。有人知道我做错了什么吗 Public Class Form1 Delegate Sub myDelegate1(ByVal s_Name As Control, ByVal s_txt As String) P
Public Class Form1
Delegate Sub myDelegate1(ByVal s_Name As Control, ByVal s_txt As String)
Public txtUpdate As New myDelegate1(AddressOf upd_ControlTextProperty)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Text = vbnullstring
End Sub
Private Sub upd_ControlTextProperty(ByVal ControlName As Control, ByVal txt As String)
ControlName.Text = txt
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim thread1 As New Threading.Thread(AddressOf threadstart)
thread1.IsBackground = True
thread1.Start()
End Sub
Private Sub threadstart()
Me.Invoke(Me.txtUpdate, New Object(), {Label1, "This is Label 1"})
End Sub
End Class
正如ValyreanGroup所说,您的代表应该接受两个参数,然后您传递三个:
Me.Invoke(Me.txtUpdate, New Object(), {Label1, "This is Label 1"})
^-1--------^ ^-2--------^ ^-3-----------------------^
因此,只需删除新对象()
对象,并将此{Label1,…}
转换为一个字符串:
Me.Invoke(Me.txtUpdate, "This is Label 1")
好吧,这样更好
另一方面,你所做的不是很有用
- 您可以从UI线程创建一个新线程
- 有了这个新线程,您可以调用回UI线程并停止线程
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Text = vbnullstring
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Label1.Text = "This is Label 1"
End Sub
End Class
更新
(来自评论)
更清楚地说,这里有一个模式(我采用了这个模式,如果有任何限制,我将删除该图像)
主UI线程用于以下各项:
- 对用户事件(点击、输入…)做出反应,并启动执行该过程的后台线程
- 在后台线程结束或任务期间更新用户界面
当我说你所做的没有用是因为你的后台线程没有做任何处理,它只是通知UI线程更新UI…我会尝试这种方法。可以从UI线程或新线程成功调用upd_ControlTextProperty
Public Class Form1
Delegate Sub myDelegate1(ByVal s_Name As Control, ByVal s_txt As String)
Public txtUpdate As New myDelegate1(AddressOf upd_ControlTextProperty)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Text = ""
End Sub
Private Sub upd_ControlTextProperty(ByVal ControlName As Control, ByVal txt As String)
If Me.InvokeRequired = True Then
Me.Invoke(txtUpdate, New Object() {ControlName, txt})
Else
ControlName.Text = txt
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim thread1 As New Threading.Thread(AddressOf threadstart)
thread1.IsBackground = True
thread1.Start()
End Sub
Private Sub threadstart()
upd_ControlTextProperty(Label1, "This is Label 1")
End Sub
End Class
你传递了3个参数,但是回调只需要2个。这让我很困惑,msdn的一个例子也传递了3个参数,但是回调只需要1个。嘿,谢谢你!我理解,使用按钮单击事件或从表单本身更新控件的属性更简单。这只是我理解和应用学员的一个练习。另一方面,为什么说从UI线程创建一个新线程没有用呢?我的意思是,线程应该在哪里创建?你能详细说明一下吗?从UI线程开始一个新线程没有问题。这个问题更多的是为了新线程的目的,它被设计为同时运行两个异步进程。如果新线程的主要目的是更新UI,那么将有对UI线程的连续回调来执行更新。因此,在第二个线程上运行这样的操作不是最佳的,因为UI更新可以由单个UI线程处理。@printf更新了我的答案,以便您可以更清楚地了解后台线程的使用