none
Passing multiple byref variables: Variables fail to change in calling function using Me.Invoke() RRS feed

  • Question

  • I have code, shown below, that works all except for 1 thing: The variables being passed byRef get passed, but once modified in the else section of the "if me.invokerequired" code of RecordData, the variables are never updated in the calling function. To reiterate, the calling function does not receive the updated data that is in the variables custid and amt.

    When debugging, I see the data change in the else section of "if me.invokerequired", but once it returns from the callback the data is missing.

    What am I not doing, what have I done wrong? Thanks for any help!

    Edit: I realized the code I modified had some things that didn't make sense... So here it is so it hopefully makes sense:

    'This code is in the form:
    Dim WithEvents oServer As ServerClass
    Dim ServerThread As Thread
    sub StartThread()
     If oServer Is Nothing Then
      oServer = New ServerClass
     End If
     ServerThread = New Thread(AddressOf oServer.WaitForData)
     ServerThread.Start()
    end sub
    Delegate Sub RecordDataCallback(ByRef custid As String, ByRef amt As Double)
    Sub RecordData(ByRef custid As String, ByRef amt As Double) Handles oServer.ThreadProcess
     If Me.InvokeRequired Then
      Dim d As New RecordDataCallback(AddressOf RecordData) 
      Me.Invoke(d, New Object() {custid, amt})
      'data does not get returned from the invoke... thus data does not make it to the calling function.
     Else
      custid = "myuser"
      amt = 20.00  
      'data is successfully altered
     End If
    End Sub
    
    'In the thread class:
    Public Event ThreadProcess(ByRef custid As String, ByRef amt As Double)
    
    'this code is started as a thread in form, I'm not showing the
    'whole sub cause it's long and all works:
    public sub WaitForData()
    'again, lots of code not here for simplicity sake
    dim customerid as string = "-1"
    dim amount as double = -1.00
    RaiseEvent RecordData(customerid, amount)
    msgbox("custid=" & customerid)
    msgbox("amt=" & amount)
    'output: custid=-1
    'output: amt=-1
    end sub

    • Edited by KyferEz Tuesday, September 28, 2010 8:11 PM more clarifications
    Monday, September 27, 2010 7:12 AM

Answers

  • This is the correct behavior.  The Control.Invoke method itself does not have any ByRef parameters, hence the ByRef "chain" is broken which by outward appearances makes it work like ByVal.  Consider passing an object as the parameter.  This will pass a reference to the object (even if the parameter declared ByVal, as would actually be preferred in this case).  Any method calls or properties on the object will affect the passed instance, thus letting you set data that could be passed back.  Another solution would be to change the delegate to a function and make use of the function return value.  The Invoke method itself will return this value, which you can then DirectCast to the correct type.

     

     

    • Marked as answer by SamAgain Wednesday, September 29, 2010 3:12 AM
    Monday, September 27, 2010 11:22 PM