Need help with INVOKE/DELEGATE

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Terry Olsen

    Need help with INVOKE/DELEGATE

    I'm running an asynchronous Socket. In the ReceiveCallback method, I need
    to append what is received to a textbox on the main form. I have this code:

    Private Sub ToChatWindow(By Val msg As String)
    txtChat.AppendT ext(msg)
    End Sub

    I've never used a delegate or invoke before and I'm rather confused on the
    topic. Hope someone can help.

    Thanks.


  • Bart Mermuys

    #2
    Re: Need help with INVOKE/DELEGATE

    Hi,

    "Terry Olsen" <tolsen64@hotma il.com> wrote in message
    news:%237qHwIdC GHA.1288@TK2MSF TNGP09.phx.gbl. ..[color=blue]
    > I'm running an asynchronous Socket. In the ReceiveCallback method, I need
    > to append what is received to a textbox on the main form. I have this
    > code:
    >
    > Private Sub ToChatWindow(By Val msg As String)
    > txtChat.AppendT ext(msg)
    > End Sub
    >
    > I've never used a delegate or invoke before and I'm rather confused on the
    > topic. Hope someone can help.
    >[/color]

    1) You first define a delegate, to understand delegates better, you have to
    know the compiler creates a class that can wrap a sub or function with the
    same signature for each delegate you define. Like other classes a delegate
    can be used as a variable and can be instantiated, the constructor takes a
    sub or function that matches the delegate signature. BUT, in VB.NET
    AddressOf returns an instantiated delegate, so you don't need to explicitly
    use the delegate's constructor.

    2) When ToChatWindow is called, we check if InvokeRequired is needed (eg.
    when you call from an other thread) and if it is needed, then we call
    txtChat.Invoke which will invoke ToChatWindow again (through a delegate
    instance), but this time it runs on the UI thread and InvokeRequired will be
    false.

    Public Class SomeForm
    Inherits Form

    ' define delegate ( signature matches ToChatWindow )
    Private Delegate Sub ToChatWindowHan dler( msg As String )

    ' delegate instance
    Private ToChatWindowHan dlerInst As ToChatWindowHan dler

    Public Sub New()
    ' create delegate instance
    ToChatWindowHan dlerInst = AddressOf ToChatWindow
    End Sub

    Public Sub ToChatWindow( msg As String )
    If ( txtChat.InvokeR equired ) Then
    txtChat.Invoke( ToChatWindowHan dlerInst, _
    New Object() { msg } )
    Return ' dont forget
    End If

    ' at this point you are in UI thread
    txtChat.AppendT ext( msg )
    End Sub

    End Class


    Don't want to confuse you, but notice that you can also call
    SomeDelegateIns tance.Invoke(<p arameters>), but this will just invoke the
    wrapped function without marshalling it to the UI thread unlike
    Control.Invoke( SomeDelegateIns tance, <parameters>) which does marshall to
    the UI thread(which is the thread that created the Control).

    And one more thing, there is Control.Invoke and Control.InvokeL ater, the
    former will wait until the function has run on the UI thread, the latter
    will not wait until it is run and return immediately.

    HTH,
    Greetings


    [color=blue]
    > Thanks.
    >[/color]


    Comment

    • Terry Olsen

      #3
      Re: Need help with INVOKE/DELEGATE

      So the following code goes in Form1's NEW method?
      [color=blue]
      > Public Sub New()
      > ' create delegate instance
      > ToChatWindowHan dlerInst = AddressOf ToChatWindow
      > End Sub[/color]


      Comment

      • Bart Mermuys

        #4
        Re: Need help with INVOKE/DELEGATE

        Hi,

        "Terry Olsen" <tolsen64@hotma il.com> wrote in message
        news:u9fQ0llCGH A.1312@TK2MSFTN GP09.phx.gbl...[color=blue]
        > So the following code goes in Form1's NEW method?[/color]

        Yes, that's the idea, you need an instantiated delegate so why not do it in
        the form's constructor (Sub New), you could also use Form_Load, if you have
        any problems with it or with the code explain where you think it goes wrong.

        Usually a Form already has a New method, so it should look like:

        Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeCompo nent()

        ' Add any initialization after the InitializeCompo nent() call.
        ToChatWindowHan dlerInst = AddressOf ToChatWindow
        End Sub

        HTH,
        Greetings
        [color=blue]
        >[color=green]
        >> Public Sub New()
        >> ' create delegate instance
        >> ToChatWindowHan dlerInst = AddressOf ToChatWindow
        >> End Sub[/color][/color]
        [color=blue]
        >[/color]



        Comment

        • Terry Olsen

          #5
          Re: Need help with INVOKE/DELEGATE

          Thanks for the help. I was able to simplify it and I came up with this,
          which works great!

          Delegate Sub ToChatWindowDel egate(ByVal msg As String)

          Private Sub ToChatWindow(By Val msg As String)
          If txtChat.InvokeR equired Then
          txtChat.Invoke( New ToChatWindowDel egate(AddressOf ToChatWindow), New
          Object() {msg})
          Else
          txtChat.AppendT ext(msg)
          End If
          End Sub


          Comment

          • Bart Mermuys

            #6
            Re: Need help with INVOKE/DELEGATE

            Hi,

            "Terry Olsen" <tolsen64@hotma il.com> wrote in message
            news:OD0XG4lCGH A.216@TK2MSFTNG P15.phx.gbl...[color=blue]
            > Thanks for the help. I was able to simplify it and I came up with this,
            > which works great!
            >
            > Delegate Sub ToChatWindowDel egate(ByVal msg As String)
            >
            > Private Sub ToChatWindow(By Val msg As String)
            > If txtChat.InvokeR equired Then
            > txtChat.Invoke( New ToChatWindowDel egate(AddressOf ToChatWindow), New
            > Object() {msg})
            > Else
            > txtChat.AppendT ext(msg)
            > End If
            > End Sub
            >[/color]

            That's ok too and i almost posted that, but then changed it, because
            ToChatWindow could be called alot and each AddressOf creates a new
            instantiated delegate, so to avoid re-creating the delegate each time, i
            used a delegate field and created the delegate inside the ctor.

            Greetings

            [color=blue]
            >[/color]


            Comment

            • Dennis

              #7
              Re: Need help with INVOKE/DELEGATE

              Thank-you for the excellent code..I learned a lot from it.
              --
              Dennis in Houston


              "Bart Mermuys" wrote:
              [color=blue]
              > Hi,
              >
              > "Terry Olsen" <tolsen64@hotma il.com> wrote in message
              > news:OD0XG4lCGH A.216@TK2MSFTNG P15.phx.gbl...[color=green]
              > > Thanks for the help. I was able to simplify it and I came up with this,
              > > which works great!
              > >
              > > Delegate Sub ToChatWindowDel egate(ByVal msg As String)
              > >
              > > Private Sub ToChatWindow(By Val msg As String)
              > > If txtChat.InvokeR equired Then
              > > txtChat.Invoke( New ToChatWindowDel egate(AddressOf ToChatWindow), New
              > > Object() {msg})
              > > Else
              > > txtChat.AppendT ext(msg)
              > > End If
              > > End Sub
              > >[/color]
              >
              > That's ok too and i almost posted that, but then changed it, because
              > ToChatWindow could be called alot and each AddressOf creates a new
              > instantiated delegate, so to avoid re-creating the delegate each time, i
              > used a delegate field and created the delegate inside the ctor.
              >
              > Greetings
              >
              >[color=green]
              > >[/color]
              >
              >
              >[/color]

              Comment

              • Bart Mermuys

                #8
                Re: Need help with INVOKE/DELEGATE

                Hi,

                "Dennis" <Dennis@discuss ions.microsoft. com> wrote in message
                news:1E423D36-FB97-4851-9037-51ADD76E9B56@mi crosoft.com...[color=blue]
                > Thank-you for the excellent code..I learned a lot from it.[/color]

                You're welcome, it is a commonly used pattern that i explained a bit.

                Greetings

                [color=blue]
                > --
                > Dennis in Houston
                >
                >
                > "Bart Mermuys" wrote:
                >[color=green]
                >> Hi,
                >>
                >> "Terry Olsen" <tolsen64@hotma il.com> wrote in message
                >> news:OD0XG4lCGH A.216@TK2MSFTNG P15.phx.gbl...[color=darkred]
                >> > Thanks for the help. I was able to simplify it and I came up with
                >> > this,
                >> > which works great!
                >> >
                >> > Delegate Sub ToChatWindowDel egate(ByVal msg As String)
                >> >
                >> > Private Sub ToChatWindow(By Val msg As String)
                >> > If txtChat.InvokeR equired Then
                >> > txtChat.Invoke( New ToChatWindowDel egate(AddressOf ToChatWindow), New
                >> > Object() {msg})
                >> > Else
                >> > txtChat.AppendT ext(msg)
                >> > End If
                >> > End Sub
                >> >[/color]
                >>
                >> That's ok too and i almost posted that, but then changed it, because
                >> ToChatWindow could be called alot and each AddressOf creates a new
                >> instantiated delegate, so to avoid re-creating the delegate each time, i
                >> used a delegate field and created the delegate inside the ctor.
                >>
                >> Greetings
                >>
                >>[color=darkred]
                >> >[/color]
                >>
                >>
                >>[/color][/color]


                Comment

                • Terry Olsen

                  #9
                  Re: Need help with INVOKE/DELEGATE

                  I see your point, but doesn't the delegate go away when the method it calls
                  exits?

                  "Bart Mermuys" <bmermuys.nospa m@hotmail.com> wrote in message
                  news:%236WnANmC GHA.3812@TK2MSF TNGP15.phx.gbl. ..[color=blue]
                  > Hi,
                  >
                  > "Terry Olsen" <tolsen64@hotma il.com> wrote in message
                  > news:OD0XG4lCGH A.216@TK2MSFTNG P15.phx.gbl...[color=green]
                  >> Thanks for the help. I was able to simplify it and I came up with this,
                  >> which works great!
                  >>
                  >> Delegate Sub ToChatWindowDel egate(ByVal msg As String)
                  >>
                  >> Private Sub ToChatWindow(By Val msg As String)
                  >> If txtChat.InvokeR equired Then
                  >> txtChat.Invoke( New ToChatWindowDel egate(AddressOf ToChatWindow), New
                  >> Object() {msg})
                  >> Else
                  >> txtChat.AppendT ext(msg)
                  >> End If
                  >> End Sub
                  >>[/color]
                  >
                  > That's ok too and i almost posted that, but then changed it, because
                  > ToChatWindow could be called alot and each AddressOf creates a new
                  > instantiated delegate, so to avoid re-creating the delegate each time, i
                  > used a delegate field and created the delegate inside the ctor.
                  >
                  > Greetings
                  >
                  >[color=green]
                  >>[/color]
                  >
                  >[/color]


                  Comment

                  • Bart Mermuys

                    #10
                    Re: Need help with INVOKE/DELEGATE

                    Hi,

                    "Terry Olsen" <tolsen64@hotma il.com> wrote in message
                    news:%23GwlmAvC GHA.3820@TK2MSF TNGP12.phx.gbl. ..[color=blue]
                    >I see your point, but doesn't the delegate go away when the method it calls
                    >exits?[/color]

                    After Invoke there is no reference anymore, so it/they will be cleaned up
                    the next time GC runs, but that wasn't really the point.
                    It may be a personal thing, but i don't like the idea to create a new
                    delegate instance each time the function is called expecially when there is
                    an easy way to avoid it and the function is called repeatedly.
                    Performance-wise it may not differ that much.

                    Greetings
                    [color=blue]
                    >
                    > "Bart Mermuys" <bmermuys.nospa m@hotmail.com> wrote in message
                    > news:%236WnANmC GHA.3812@TK2MSF TNGP15.phx.gbl. ..[color=green]
                    >> Hi,
                    >>
                    >> "Terry Olsen" <tolsen64@hotma il.com> wrote in message
                    >> news:OD0XG4lCGH A.216@TK2MSFTNG P15.phx.gbl...[color=darkred]
                    >>> Thanks for the help. I was able to simplify it and I came up with this,
                    >>> which works great!
                    >>>
                    >>> Delegate Sub ToChatWindowDel egate(ByVal msg As String)
                    >>>
                    >>> Private Sub ToChatWindow(By Val msg As String)
                    >>> If txtChat.InvokeR equired Then
                    >>> txtChat.Invoke( New ToChatWindowDel egate(AddressOf ToChatWindow), New
                    >>> Object() {msg})
                    >>> Else
                    >>> txtChat.AppendT ext(msg)
                    >>> End If
                    >>> End Sub
                    >>>[/color]
                    >>
                    >> That's ok too and i almost posted that, but then changed it, because
                    >> ToChatWindow could be called alot and each AddressOf creates a new
                    >> instantiated delegate, so to avoid re-creating the delegate each time, i
                    >> used a delegate field and created the delegate inside the ctor.
                    >>
                    >> Greetings
                    >>
                    >>[color=darkred]
                    >>>[/color]
                    >>
                    >>[/color]
                    >
                    >[/color]


                    Comment

                    Working...