Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
203 views
in Technique[技术] by (71.8m points)

multithreading - Modifying the properties of controls from another thread in VB.net

Is it possible to modify the properties of a forms controls from another thread without creating a separate method and delegate for each property that you want to modify?

I am currently writing a multithreaded application where I need background threads to manipulate the userinterface. I feel like the amount of code that I am writing to do simple tasks such as setting a control's text property is huge compared to the code I would write for a single threaded app.

In a single threaded app, one can simply use Control.text = "My Text", but so far when creating a multithreaded application, I need all of the following just to perform the same task in a thread safe way.

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

I have plenty of similar code that seems equally long for such simple tasks:

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're adding a lot of unnecessary code with the delegate and the array. The addressof and {} syntax's both create instances so you don't need the constructors or declaration leaving you with:

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

This is real actively clean and if your UI is separate from your logic a low overhead. If this is still a problem look to see if you can refactor to groups of ui changes in a single method to accomplish a task rather than invoking a single change. These methods can then be cleanly protected.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...