Invoking a function from within a class...

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • hurricane_number_one@yahoo.com

    Invoking a function from within a class...

    I'm trying to have a class, which uses threads be able to raise events
    to the form that created it. I've seen solutions around the net for
    this, but I didn't really like their implementation. Most involve
    passing the form into the class, or require a lot of coding. All I
    really need to do is be able to have my thread call a function within
    that class which runs on the same thread as the class. I've done this
    from within forms, but can't figure out how to do it within a class
    (see my comment below). How do I invoke the function from the thread
    that the class is created on? I don't want the form to have to invoke
    it. Any suggestions?

    Public Class myClass

    Dim myThread As Thread

    Private client As Socket

    Public Sub start()

    myThread = New Thread(AddressO f threadFun)
    myThread .Start()

    End Sub

    Private Sub threadFun()

    raiseThisEvent( CLASS_EVENTS.ST ART)

    End Sub

    Delegate Sub thisEventDelega te(ByVal thisEvent As CLASS_EVENTS)

    Public Sub raiseThisEvent( ByVal thisEvent As CLASS_EVENTS)

    if thisEvent = CLASS_EVENTS.ST ART then
    RaiseEvent onStart()
    end if

    End Sub

    Public Sub raiseClassEvent (ByVal thisEvent As CLASS_EVENTS)

    Dim passDelegate As New thisEventDelega te(AddressOf
    raiseThisEvent)

    ' **** This is what I'd do if it were in a form, how do I do
    the same within a class?? ****
    Me.Invoke(passD elegate, thisEvent)
    ' ****

    End Sub

    end class
  • Tom Shelton

    #2
    Re: Invoking a function from within a class...

    On 2008-06-25, hurricane_numbe r_one@yahoo.com <hurricane_numb er_one@yahoo.co mwrote:
    I'm trying to have a class, which uses threads be able to raise events
    to the form that created it. I've seen solutions around the net for
    this, but I didn't really like their implementation. Most involve
    passing the form into the class, or require a lot of coding. All I
    really need to do is be able to have my thread call a function within
    that class which runs on the same thread as the class. I've done this
    from within forms, but can't figure out how to do it within a class
    (see my comment below). How do I invoke the function from the thread
    that the class is created on? I don't want the form to have to invoke
    it. Any suggestions?
    >
    Public Class myClass
    >
    Dim myThread As Thread
    >
    Private client As Socket
    >
    Public Sub start()
    >
    myThread = New Thread(AddressO f threadFun)
    myThread .Start()
    >
    End Sub
    >
    Private Sub threadFun()
    >
    raiseThisEvent( CLASS_EVENTS.ST ART)
    >
    End Sub
    >
    Delegate Sub thisEventDelega te(ByVal thisEvent As CLASS_EVENTS)
    >
    Public Sub raiseThisEvent( ByVal thisEvent As CLASS_EVENTS)
    >
    if thisEvent = CLASS_EVENTS.ST ART then
    RaiseEvent onStart()
    end if
    >
    End Sub
    >
    Public Sub raiseClassEvent (ByVal thisEvent As CLASS_EVENTS)
    >
    Dim passDelegate As New thisEventDelega te(AddressOf
    raiseThisEvent)
    >
    ' **** This is what I'd do if it were in a form, how do I do
    the same within a class?? ****
    Me.Invoke(passD elegate, thisEvent)
    ' ****
    >
    End Sub
    >
    end class
    You, take the form as ISyncronizeInvo ke parameter to your constructor. And
    then use invoke and begin invoke from that interface. It seems, you don't like
    that solution, but it is really the simplest and most flexable. First, you
    don't have to care if it's a form or a cookpot being passed, as long as it
    implments ISyncronizeInvo ke - and second, you can allow nothhing to avoid
    syncronization all together if you don't need it:

    public class NeedsSync
    privatte _syncObject As ISyncronizeInvo ke

    public sub new()
    ' do stuff
    _syncObject = nothing
    end sub

    public sub new(byval syncObject as ISyncronizeInvo ke)
    me.new()
    _syncObject = syncObject
    end sub

    ' do a bunch of stuff

    private sub InvokeADelegate (byval del as delegate, byval params() as
    object)
    if not _syncOjbect is nothing then
    _syncOjbect.Inv oke (delegate, params)
    else
    raiseevent delegate, params
    end if
    end sub
    end class

    Anyway, that is a bunch of air code (and not completely syntactically correct)
    - but I think it should give you an idea of what I'm saying.

    --
    Tom Shelton

    Comment

    • Tom Shelton

      #3
      Re: Invoking a function from within a class...

      On 2008-06-25, Tom Shelton <tom_shelton@co mcastXXXXXXX.ne twrote:
      On 2008-06-25, hurricane_numbe r_one@yahoo.com <hurricane_numb er_one@yahoo.co mwrote:
      >I'm trying to have a class, which uses threads be able to raise events
      >to the form that created it. I've seen solutions around the net for
      >this, but I didn't really like their implementation. Most involve
      >passing the form into the class, or require a lot of coding. All I
      >really need to do is be able to have my thread call a function within
      >that class which runs on the same thread as the class. I've done this
      >from within forms, but can't figure out how to do it within a class
      >(see my comment below). How do I invoke the function from the thread
      >that the class is created on? I don't want the form to have to invoke
      >it. Any suggestions?
      >>
      >
      <snip>

      By the way, you can also check for InvokeRequired if you'd like :)

      private sub InvokeADelegate (byval del as delegate, byval params() as object)
      if not _syncOjbect is nothing andalso _syncObject.Inv okeRequired then
      _syncOjbect.Inv oke (delegate, params)
      else
      raiseevent delegate, params
      end if
      end sub


      --
      Tom Shelton

      Comment

      • hurricane_number_one@yahoo.com

        #4
        Re: Invoking a function from within a class...

        Thanks, but I think I may be a bit unclear as to how to use this (I'm
        new to .NET). In your code, what calls the InvokeADelegate function?
        What is the delegate that gets passed in? Could you provide an
        example of how this is called?

        What happens if the syncObject doesn't implement the delegate
        function? Using this, wouldn't the form need to implement every event
        that the class raises?

        Is there any simpler way to just get the class to call a function from
        within a thread that can raise an event from the same thread as the
        caller?

        If the thread is just raising events that basically pass status
        messages back to the form, does this really need to be thread safe?
        What's the dangers that all of this is protecting me from?

        I wonder if I should just have the thread set flags as to the state of
        the object (i.e. connected, disconnected, err, ect) and have the main
        form use a timer to just poll the object flag and update the UI when
        the state changes?

        Thanks for your help!!


        On Jun 25, 8:56 pm, Tom Shelton <tom_shel...@co mcastXXXXXXX.ne t>
        wrote:
        On 2008-06-25, Tom Shelton <tom_shel...@co mcastXXXXXXX.ne twrote:
        >
        On 2008-06-25, hurricane_numbe r_...@yahoo.com <hurricane_numb er_...@yahoo.co mwrote:
        I'm trying to have a class, which uses threads be able to raise events
        to the form that created it.  I've seen solutions around the net for
        this, but I didn't really like their implementation.  Most involve
        passing the form into the class, or require a lot of coding.  All I
        really need to do is be able to have my thread call a function within
        that class which runs on the same thread as the class.  I've done this
        from within forms, but can't figure out how to do it within a class
        (see my comment below). How do I invoke the function from the thread
        that the class is created on? I don't want the form to have to invoke
        it.  Any suggestions?
        >
        <snip>
        >
        By the way, you can also check for InvokeRequired if you'd like :)
        >
        private sub InvokeADelegate (byval del as delegate, byval params() as object)
                if not _syncOjbect is nothing andalso _syncObject.Inv okeRequired then
                        _syncOjbect.Inv oke (delegate, params)
                else
                        raiseevent delegate, params
                end if
        end sub
        >
        --
        Tom Shelton

        Comment

        • Tom Shelton

          #5
          Re: Invoking a function from within a class...

          On Jun 25, 7:50 pm, hurricane_numbe r_...@yahoo.com wrote:
          Thanks, but I think I may be a bit unclear as to how to use this (I'm
          new to .NET).  In your code, what calls the InvokeADelegate function?
          What is the delegate that gets passed in?  Could you provide an
          example of how this is called?
          >
          What happens if the syncObject doesn't implement the delegate
          function?  Using this, wouldn't the form need to implement every event
          that the class raises?
          >
          Is there any simpler way to just get the class to call a function from
          within a thread that can raise an event from the same thread as the
          caller?
          >
          If the thread is just raising events that basically pass status
          messages back to the form, does this really need to be thread safe?
          What's the dangers that all of this is protecting me from?
          >
          I wonder if I should just have the thread set flags as to the state of
          the object (i.e. connected, disconnected, err, ect) and have the main
          form use a timer to just poll the object flag and update the UI when
          the state changes?
          >
          Thanks for your help!!
          >
          On Jun 25, 8:56 pm, Tom Shelton <tom_shel...@co mcastXXXXXXX.ne t>
          wrote:
          >
          >
          >
          On 2008-06-25, Tom Shelton <tom_shel...@co mcastXXXXXXX.ne twrote:
          >
          On 2008-06-25, hurricane_numbe r_...@yahoo.com <hurricane_numb er_...@yahoo.co mwrote:
          >I'm trying to have a class, which uses threads be able to raise events
          >to the form that created it.  I've seen solutions around the net for
          >this, but I didn't really like their implementation.  Most involve
          >passing the form into the class, or require a lot of coding.  All I
          >really need to do is be able to have my thread call a function within
          >that class which runs on the same thread as the class.  I've done this
          >from within forms, but can't figure out how to do it within a class
          >(see my comment below). How do I invoke the function from the thread
          >that the class is created on? I don't want the form to have to invoke
          >it.  Any suggestions?
          >
          <snip>
          >
          By the way, you can also check for InvokeRequired if you'd like :)
          >
          private sub InvokeADelegate (byval del as delegate, byval params() as object)
                  if not _syncOjbect is nothing andalso _syncObject.Inv okeRequired then
                          _syncOjbect.Inv oke (delegate, params)
                  else
                          raiseevent delegate, params
                  end if
          end sub
          >
          --
          Tom Shelton- Hide quoted text -
          >
          - Show quoted text -
          Ok... here is a complete working example. The form, is simply a form
          with a ListBox on it named uxpOutput. It has it's IntegralHeight
          property set to false and it is docked to fill the form:

          Option Strict On
          Option Explicit On
          Option Infer Off


          Public Class MainForm
          Private _t As Worker
          Private Sub MainForm_Load(B yVal sender As System.Object, ByVal e
          As System.EventArg s) Handles MyBase.Load
          _t = New Worker(Me)
          AddHandler _t.Event1, AddressOf Event1
          AddHandler _t.Event2, AddressOf Event2
          AddHandler _t.event3, AddressOf Event3
          _t.Start()
          End Sub

          Private Sub Event1(ByVal sender As Object, ByVal e As EventArgs)
          uxpOutput.Items .Add("Event1 Called")
          End Sub
          Private Sub Event2(ByVal sender As Object, ByVal e As EventArgs)
          uxpOutput.Items .Add("Event2 Called")
          End Sub
          Private Sub Event3(ByVal sender As Object, ByVal e As EventArgs)
          uxpOutput.Items .Add("Event3 Called")
          End Sub

          Private Sub MainForm_FormCl osing(ByVal sender As System.Object,
          ByVal e As System.Windows. Forms.FormClosi ngEventArgs) Handles
          MyBase.FormClos ing
          _t.Stop()
          End Sub
          End Class

          Here is the Worker definition:

          Option Strict On
          Option Explicit On
          Option Infer Off

          Imports System
          Imports System.Componen tModel
          Imports System.Threadin g

          Public Class Worker
          Private _syncObject As ISynchronizeInv oke
          Private _runner As Thread
          Private _cancel As Boolean

          Public Sub New(ByVal syncObject As ISynchronizeInv oke)
          _syncObject = syncObject
          End Sub

          Public Event Event1 As EventHandler
          Public Event Event2 As EventHandler
          Public Event Event3 As EventHandler

          Public Sub [Start]()
          If Not _cancel Then
          _runner = New Thread(AddressO f DoWork)
          _runner.Start()
          End If
          End Sub

          Public Sub [Stop]()
          _cancel = True
          _runner.Join()
          End Sub

          Private Sub DoWork()
          Dim i As Integer
          Dim r As New Random()

          Do Until _cancel
          i = r.Next(1, 31)
          Select Case i
          Case 1 To 10
          RaiseAnEvent(Ev ent1Event, New Object() {Me, New
          EventArgs()})
          Case 11 To 20
          RaiseAnEvent(Ev ent2Event, New Object() {Me, New
          EventArgs()})
          Case 21 To 30
          RaiseAnEvent(Ev ent3Event, New Object() {Me, New
          EventArgs()})
          End Select
          Thread.Sleep(10 00)
          Loop
          End Sub

          Private Sub RaiseAnEvent(By Val d As [Delegate], ByVal args() As
          Object)
          If Not d Is Nothing Then
          If _syncObject Is Nothing Or Not
          _syncObject.Inv okeRequired Then
          d.Method.Invoke (d.Target, args)
          Else
          _syncObject.Inv oke(d, args)
          End If
          End If
          End Sub

          End Class

          Anyway, if you comment out the addhandler statements, you will see
          that only the events you subscribe to are raised - and they are raised
          on the right thread :)

          HTH

          --
          Tom Shelton

          Comment

          • hurricane_number_one@yahoo.com

            #6
            Re: Invoking a function from within a class...

            Thanks for your help, I'll give that a shot.

            On Jun 26, 1:45 am, Tom Shelton <tom_shel...@co mcast.netwrote:
            On Jun 25, 7:50 pm, hurricane_numbe r_...@yahoo.com wrote:
            >
            >
            >
            Thanks, but I think I may be a bit unclear as to how to use this (I'm
            new to .NET).  In your code, what calls the InvokeADelegate function?
            What is the delegate that gets passed in?  Could you provide an
            example of how this is called?
            >
            What happens if the syncObject doesn't implement the delegate
            function?  Using this, wouldn't the form need to implement every event
            that the class raises?
            >
            Is there any simpler way to just get the class to call a function from
            within a thread that can raise an event from the same thread as the
            caller?
            >
            If the thread is just raising events that basically pass status
            messages back to the form, does this really need to be thread safe?
            What's the dangers that all of this is protecting me from?
            >
            I wonder if I should just have the thread set flags as to the state of
            the object (i.e. connected, disconnected, err, ect) and have the main
            form use a timer to just poll the object flag and update the UI when
            the state changes?
            >
            Thanks for your help!!
            >
            On Jun 25, 8:56 pm, Tom Shelton <tom_shel...@co mcastXXXXXXX.ne t>
            wrote:
            >
            On 2008-06-25, Tom Shelton <tom_shel...@co mcastXXXXXXX.ne twrote:
            >
            On 2008-06-25, hurricane_numbe r_...@yahoo.com <hurricane_numb er_...@yahoo.co mwrote:
            I'm trying to have a class, which uses threads be able to raise events
            to the form that created it.  I've seen solutions around the netfor
            this, but I didn't really like their implementation.  Most involve
            passing the form into the class, or require a lot of coding.  All I
            really need to do is be able to have my thread call a function within
            that class which runs on the same thread as the class.  I've done this
            from within forms, but can't figure out how to do it within a class
            (see my comment below). How do I invoke the function from the thread
            that the class is created on? I don't want the form to have to invoke
            it.  Any suggestions?
            >
            <snip>
            >
            By the way, you can also check for InvokeRequired if you'd like :)
            >
            private sub InvokeADelegate (byval del as delegate, byval params() asobject)
                    if not _syncOjbect is nothing andalso _syncObject.Inv okeRequired then
                            _syncOjbect.Inv oke (delegate, params)
                    else
                            raiseevent delegate, params
                    end if
            end sub
            >
            --
            Tom Shelton- Hide quoted text -
            >
            - Show quoted text -
            >
            Ok... here is a complete working example.  The form, is simply a form
            with a ListBox on it named uxpOutput.  It has it's IntegralHeight
            property set to false and it is docked to fill the form:
            >
            Option Strict On
            Option Explicit On
            Option Infer Off
            >
            Public Class MainForm
                Private _t As Worker
                Private Sub MainForm_Load(B yVal sender As System.Object, ByVal e
            As System.EventArg s) Handles MyBase.Load
                    _t = New Worker(Me)
                    AddHandler _t.Event1, AddressOf Event1
                    AddHandler _t.Event2, AddressOf Event2
                    AddHandler _t.event3, AddressOf Event3
                    _t.Start()
                End Sub
            >
                Private Sub Event1(ByVal sender As Object, ByVal e As EventArgs)
                    uxpOutput.Items .Add("Event1 Called")
                End Sub
                Private Sub Event2(ByVal sender As Object, ByVal e As EventArgs)
                    uxpOutput.Items .Add("Event2 Called")
                End Sub
                Private Sub Event3(ByVal sender As Object, ByVal e As EventArgs)
                    uxpOutput.Items .Add("Event3 Called")
                End Sub
            >
                Private Sub MainForm_FormCl osing(ByVal sender As System.Object,
            ByVal e As System.Windows. Forms.FormClosi ngEventArgs) Handles
            MyBase.FormClos ing
                    _t.Stop()
                End Sub
            End Class
            >
            Here is the Worker definition:
            >
            Option Strict On
            Option Explicit On
            Option Infer Off
            >
            Imports System
            Imports System.Componen tModel
            Imports System.Threadin g
            >
            Public Class Worker
                Private _syncObject As ISynchronizeInv oke
                Private _runner As Thread
                Private _cancel As Boolean
            >
                Public Sub New(ByVal syncObject As ISynchronizeInv oke)
                    _syncObject = syncObject
                End Sub
            >
                Public Event Event1 As EventHandler
                Public Event Event2 As EventHandler
                Public Event Event3 As EventHandler
            >
                Public Sub [Start]()
                    If Not _cancel Then
                        _runner = New Thread(AddressO f DoWork)
                        _runner.Start()
                    End If
                End Sub
            >
                Public Sub [Stop]()
                    _cancel = True
                    _runner.Join()
                End Sub
            >
                Private Sub DoWork()
                    Dim i As Integer
                    Dim r As New Random()
            >
                    Do Until _cancel
                        i = r.Next(1, 31)
                        Select Case i
                            Case 1 To 10
                                RaiseAnEvent(Ev ent1Event, New Object() {Me, New
            EventArgs()})
                            Case 11 To 20
                                RaiseAnEvent(Ev ent2Event, New Object() {Me, New
            EventArgs()})
                            Case 21 To 30
                                RaiseAnEvent(Ev ent3Event, New Object() {Me, New
            EventArgs()})
                        End Select
                        Thread.Sleep(10 00)
                    Loop
                End Sub
            >
                Private Sub RaiseAnEvent(By Val d As [Delegate], ByVal args() As
            Object)
                    If Not d Is Nothing Then
                        If _syncObject Is Nothing Or Not
            _syncObject.Inv okeRequired Then
                            d.Method.Invoke (d.Target, args)
                        Else
                            _syncObject.Inv oke(d, args)
                        End If
                    End If
                End Sub
            >
            End Class
            >
            Anyway, if you comment out the addhandler statements, you will see
            that only the events you subscribe to are raised - and they are raised
            on the right thread :)
            >
            HTH
            >
            --
            Tom Shelton

            Comment

            Working...