在VB.net中修改另一个线程的控件属性

时间:2013-11-06 22:12:49

标签: vb.net multithreading

是否可以从另一个线程修改表单控件的属性,而无需为要修改的每个属性创建单独的方法和委托?

我目前正在编写一个多线程应用程序,我需要后台线程来操作用户界面。我觉得我编写的代码数量与执行单个线程应用程序的代码相比,执行简单任务(如设置控件的text属性)的代码量很大。

在单线程应用程序中,可以简单地使用Control.text =“My Text”,但到目前为止,在创建多线程应用程序时,我需要以下所有内容才能以线程安全的方式执行相同的任务。 / p>

Delegate Sub ChangeTextDelegate(ByVal ctrl As Control, ByVal str As String)

Private Sub ChangeText(ByVal ctrl As Control, ByVal str As String)
    If ctrl.InvokeRequired Then
        ctrl.Invoke(New ChangeTextDelegate(AddressOf ChangeText), New Object() {ctrl, str})
        Return
    End If
    ctrl.Text = str
End Sub

我有很多类似的代码,对于这些简单的任务来说似乎同样长:

Delegate Sub ChangeVisibilityDelegate(ByVal ctrl As Control, ByVal bool As Boolean)

Private Sub ChangeVisibility(ByVal ctrl As Control, ByVal bool As Boolean)
    If ctrl.InvokeRequired Then
        ctrl.Invoke(New ChangeVisibilityDelegate(AddressOf ChangeVisibility), New Object() {ctrl, bool})
        Return
    End If
    ctrl.Visible = bool
End Sub

2 个答案:

答案 0 :(得分:1)

您在委托和数组中添加了许多不必要的代码。地址和{}语法都创建了实例,因此您不需要构造函数或声明,只需要:

Private Sub ChangeVisibility(ByVal ctrl As Control, ByVal bool As Boolean)
    If ctrl.InvokeRequired Then
        ctrl.Invoke(AddressOf ChangeVisibility, {ctrl, bool})
        Return
    End If
    ctrl.Visible = bool
End Sub

这是真正的主动清理,如果你的UI与你的逻辑分开,开销很低。如果这仍然是一个问题,请查看是否可以在单个方法中重构ui更改组以完成任务而不是调用单个更改。这些方法可以得到干净的保护。

答案 1 :(得分:1)

在对其他语言如何处理异步函数的一些研究之后,我发现以下内容是编写大量样板代码的替代方法,以便从后台线程更改控件的属性。

下面的代码片段使用lambdas(可以在代理位置使用的匿名函数)来指定内联函数。这个概念在javascript中很常见,但我发现它在VB.NET中也是一个可行的选择。

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Dim trd As New Threading.Thread(Sub()
                                            Invoke(Sub()
                                                       TextBox1.Visible = False
                                                   End Sub)
                                        End Sub)
        trd.IsBackground = True
        trd.Start()
    End Sub
End Class