tags:

views:

31

answers:

1

I'm using the below to update controls from another thread (works great) How would I call a Sub (Named UpdateList)? The UpdateList updates a listview with a list of databases on a selected SQL instance, requires no arguments.

Private Sub CompleteEventHandler(ByVal sender As Object, ByVal e As Microsoft.SqlServer.Management.Common.ServerMessageEventArgs)
    SetControlPropertyValue(Label8, "text", e.ToString)

    UpdateList()

    MessageBox.Show("Restore Complete")
End Sub

Delegate Sub SetControlValueCallback(ByVal oControl As Control, ByVal propName As String, ByVal propValue As Object)

Private Sub SetControlPropertyValue(ByVal oControl As Control, ByVal propName As String, ByVal propValue As Object)
    If (oControl.InvokeRequired) Then

        Dim d As New SetControlValueCallback(AddressOf SetControlPropertyValue)
        oControl.Invoke(d, New Object() {oControl, propName, propValue})
    Else
        Dim t As Type = oControl.[GetType]()
        Dim props As PropertyInfo() = t.GetProperties()
        For Each p As PropertyInfo In props
            If p.Name.ToUpper() = propName.ToUpper() Then
                p.SetValue(oControl, propValue, Nothing)
            End If
        Next

    End If

End Sub

Based On: http://www.shabdar.org/cross-thread-operation-not-valid.html

+1  A: 

Calling a method from an event handler is not a special case – use a normal call.

The issue here is the cross-thread call from a background thread to the GUI thread. In order to overcome it, you can place the following code at the beginning of the UpdateList code:

If Me.InvokeRequired Then
    Me.Invoke(New Action(AddressOf UpdateList))
    Return
End If
Konrad Rudolph
Hi Konrad, I've added that plus a delegate but I get an error when the UpdateList is called: "Parameter count mismatch."<code> Private Delegate Sub UpdateListboxDelegate(ByVal s As String) Public Sub UpdateList() If Me.InvokeRequired Then Me.Invoke(New UpdateListboxDelegate(AddressOf UpdateList)) Return End If 'Listview update code here End Sub<code>
madlan
@madlan: Why didn’t you just take *my* code? Furthermore, the error message says it all: your delegate has a parameter (why?) but `UpdateList` doesn’t. Or did you forget to mention that parameter? In that case, you need to pass the extra parameter to the `Invoke` call. Look at the MSDN entry of `Control.Invoke` to see how that works.
Konrad Rudolph
@Konrad, I get: too few type arguments to system.action(of T) If I use your code (On the New Action)
madlan
@madlan: Then you posted the wrong code. It compiles for me.
Konrad Rudolph
I see the problem, I only have " Action(Of T)" listed rather than just Action.... Odd.
madlan
I removed system.core reference and re-added it, seems ok now. Thanks for your advice Konrad.
madlan