By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,885 Members | 1,191 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,885 IT Pros & Developers. It's quick & easy.

Invoking a function from within a class...

P: n/a
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(AddressOf threadFun)
myThread .Start()

End Sub

Private Sub threadFun()

raiseThisEvent(CLASS_EVENTS.START)

End Sub

Delegate Sub thisEventDelegate(ByVal thisEvent As CLASS_EVENTS)

Public Sub raiseThisEvent(ByVal thisEvent As CLASS_EVENTS)

if thisEvent = CLASS_EVENTS.START then
RaiseEvent onStart()
end if

End Sub

Public Sub raiseClassEvent(ByVal thisEvent As CLASS_EVENTS)

Dim passDelegate As New thisEventDelegate(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(passDelegate, thisEvent)
' ****

End Sub

end class
Jun 27 '08 #1
Share this Question
Share on Google+
5 Replies


P: n/a
On 2008-06-25, hu******************@yahoo.com <hu******************@yahoo.comwrote:
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(AddressOf threadFun)
myThread .Start()

End Sub

Private Sub threadFun()

raiseThisEvent(CLASS_EVENTS.START)

End Sub

Delegate Sub thisEventDelegate(ByVal thisEvent As CLASS_EVENTS)

Public Sub raiseThisEvent(ByVal thisEvent As CLASS_EVENTS)

if thisEvent = CLASS_EVENTS.START then
RaiseEvent onStart()
end if

End Sub

Public Sub raiseClassEvent(ByVal thisEvent As CLASS_EVENTS)

Dim passDelegate As New thisEventDelegate(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(passDelegate, thisEvent)
' ****

End Sub

end class
You, take the form as ISyncronizeInvoke 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 ISyncronizeInvoke - and second, you can allow nothhing to avoid
syncronization all together if you don't need it:

public class NeedsSync
privatte _syncObject As ISyncronizeInvoke

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

public sub new(byval syncObject as ISyncronizeInvoke)
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.Invoke (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
Jun 27 '08 #2

P: n/a
On 2008-06-25, Tom Shelton <to*********@comcastXXXXXXX.netwrote:
On 2008-06-25, hu******************@yahoo.com <hu******************@yahoo.comwrote:
>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.InvokeRequired then
_syncOjbect.Invoke (delegate, params)
else
raiseevent delegate, params
end if
end sub
--
Tom Shelton
Jun 27 '08 #3

P: n/a
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...@comcastXXXXXXX.net>
wrote:
On 2008-06-25, Tom Shelton <tom_shel...@comcastXXXXXXX.netwrote:
On 2008-06-25, hurricane_number_...@yahoo.com <hurricane_number_...@yahoo.comwrote:
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.InvokeRequired then
* * * * * * * * _syncOjbect.Invoke (delegate, params)
* * * * else
* * * * * * * * raiseevent delegate, params
* * * * end if
end sub

--
Tom Shelton
Jun 27 '08 #4

P: n/a
On Jun 25, 7:50*pm, hurricane_number_...@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...@comcastXXXXXXX.net>
wrote:
On 2008-06-25, Tom Shelton <tom_shel...@comcastXXXXXXX.netwrote:
On 2008-06-25, hurricane_number_...@yahoo.com <hurricane_number_...@yahoo.comwrote:
>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.InvokeRequired then
* * * * * * * * _syncOjbect.Invoke (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(ByVal sender As System.Object, ByVal e
As System.EventArgs) 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_FormClosing(ByVal sender As System.Object,
ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles
MyBase.FormClosing
_t.Stop()
End Sub
End Class

Here is the Worker definition:

Option Strict On
Option Explicit On
Option Infer Off

Imports System
Imports System.ComponentModel
Imports System.Threading

Public Class Worker
Private _syncObject As ISynchronizeInvoke
Private _runner As Thread
Private _cancel As Boolean

Public Sub New(ByVal syncObject As ISynchronizeInvoke)
_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(AddressOf 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(Event1Event, New Object() {Me, New
EventArgs()})
Case 11 To 20
RaiseAnEvent(Event2Event, New Object() {Me, New
EventArgs()})
Case 21 To 30
RaiseAnEvent(Event3Event, New Object() {Me, New
EventArgs()})
End Select
Thread.Sleep(1000)
Loop
End Sub

Private Sub RaiseAnEvent(ByVal d As [Delegate], ByVal args() As
Object)
If Not d Is Nothing Then
If _syncObject Is Nothing Or Not
_syncObject.InvokeRequired Then
d.Method.Invoke(d.Target, args)
Else
_syncObject.Invoke(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
Jun 27 '08 #5

P: n/a
Thanks for your help, I'll give that a shot.

On Jun 26, 1:45*am, Tom Shelton <tom_shel...@comcast.netwrote:
On Jun 25, 7:50*pm, hurricane_number_...@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...@comcastXXXXXXX.net>
wrote:
On 2008-06-25, Tom Shelton <tom_shel...@comcastXXXXXXX.netwrote:
On 2008-06-25, hurricane_number_...@yahoo.com <hurricane_number_...@yahoo.comwrote:
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.InvokeRequired then
* * * * * * * * _syncOjbect.Invoke (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(ByVal sender As System.Object, ByVal e
As System.EventArgs) 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_FormClosing(ByVal sender As System.Object,
ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles
MyBase.FormClosing
* * * * _t.Stop()
* * End Sub
End Class

Here is the Worker definition:

Option Strict On
Option Explicit On
Option Infer Off

Imports System
Imports System.ComponentModel
Imports System.Threading

Public Class Worker
* * Private _syncObject As ISynchronizeInvoke
* * Private _runner As Thread
* * Private _cancel As Boolean

* * Public Sub New(ByVal syncObject As ISynchronizeInvoke)
* * * * _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(AddressOf 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(Event1Event, New Object() {Me, New
EventArgs()})
* * * * * * * * Case 11 To 20
* * * * * * * * * * RaiseAnEvent(Event2Event, New Object() {Me, New
EventArgs()})
* * * * * * * * Case 21 To 30
* * * * * * * * * * RaiseAnEvent(Event3Event, New Object() {Me, New
EventArgs()})
* * * * * * End Select
* * * * * * Thread.Sleep(1000)
* * * * Loop
* * End Sub

* * Private Sub RaiseAnEvent(ByVal d As [Delegate], ByVal args() As
Object)
* * * * If Not d Is Nothing Then
* * * * * * If _syncObject Is Nothing Or Not
_syncObject.InvokeRequired Then
* * * * * * * * d.Method.Invoke(d.Target, args)
* * * * * * Else
* * * * * * * * _syncObject.Invoke(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
Jun 27 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.