Events v. Delegates

S

Siegfried Heintze

I'm studying the book "Microsoft Visual Basic.NET Language Reference" and I
would like some clarify the difference between events and delegates. On page
156 I see a WinForms example of timer that uses the "WithEvents" and events.
There is another example on page 124 that shows how to use delegates to sort
an array.

I don't understand the difference between events and delegates. Are they
redundant features? How do I decide which to use?

Thanks,
Siegfried
 
M

Mr. Arnold

Siegfried Heintze said:
I'm studying the book "Microsoft Visual Basic.NET Language Reference" and
I would like some clarify the difference between events and delegates. On
page 156 I see a WinForms example of timer that uses the "WithEvents" and
events. There is another example on page 124 that shows how to use
delegates to sort an array.

I don't understand the difference between events and delegates. Are they
redundant features? How do I decide which to use?


This link should help you with events and delegates.

http://www.informit.com/articles/article.aspx?p=23020&rl=1
 
G

ge0193387

I'm studying the book "Microsoft Visual Basic.NET Language Reference" and I
would like some clarify the difference between events and delegates. On page
156 I see a WinForms example of timer that uses the "WithEvents" and events.
There is another example on page 124 that shows how to use delegates to sort
an array.

I don't understand the difference between events and delegates. Are they
redundant features? How do I decide which to use?

Thanks,
Siegfried

They're not necessarily redundant features. Withevents is the easy
way to wire up events within VB.Net and delegates and other things are
another way to wire up events in just .Net (C# is one that I know of
for sure). Wiring up events in C# is probably one of the things that
could be made easier.

As for deciding which to use, withevents is for something you plan to
use as a global variable throughout the entire code (since it has to
be a global variable), delegates will be used more for declaring
dynamic controls/objects so you can wire up the correct event at the
right time.
 
G

Guest

Hi,
While I am fairly new to all this and am still on the 'learning curve',
here is how I understand it. You can think of delegates as what events use
behind the scene. When you use the delegate keyword, you are declaring a
type (of pointer to a method).
eg Delegate Function Foo(ByVal I As Integer) As Integer
then you can instansiate a member of this type like...
Dim MyFoo As Foo = AddressOf DoSomething
solong as DoSomething is a Function that takes 1 integer argument and
returns an integer.
This is also how you accomplish 'callbacks'. A method can accept a
parameter which is declared as a 'delegate' type. eg
Sub TestRoutine(byval MyCallback as Foo)
.....
Dim Result as Integer = MyCallBack(SomeInt)
.....

Now, as I understand it, 'Events' are just that - 'CallBacks'. So, when you
'wire' a routine to an event, you are 'adding' that routines address to the
list of routines that are to be called when that event fires. Remember that
the routine you are trying to wire to the control has to have a particular
signature (ie match the delegate type that the controll expects to
'callback').

Well, I am sure there is more to this that I don't understand, but hopefully
I have not said anything that is not true. If I have I, I invite someone to
straigten me out on this.
 
R

rowe_newsgroups

I'm studying the book "Microsoft Visual Basic.NET Language Reference" and I
would like some clarify the difference between events and delegates. On page
156 I see a WinForms example of timer that uses the "WithEvents" and events.
There is another example on page 124 that shows how to use delegates to sort
an array.

I don't understand the difference between events and delegates. Are they
redundant features? How do I decide which to use?

Thanks,
Siegfried

For me, delegates basically serve two functions. This first is to sort-
of act like an Interface for a single method. When you create a
delegate, you specify the necessary method signature (return value and
parameters) that are needed to map a method to a delegate. This
relationship becomes more obvious when you look at an example of
creating a custom event.

Suppose we want to create a custom event that will expose a special
property to the event handler. One way to do this is to create a new
class that inherits from EventArgs and contains this additional
property. Once we've done that, we must define a delegate to force any
handler to have an instance of the class we just created. Finally, we
can then add the new event to our class:

////////////////////
Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'// Raise our event
OnMyCustomEvent(New MyCustomEventArgs("hello, world"))
End Sub

'// Your custom event
Public Event MyCustomEvent As MyCustomEventHandler

'// Internal method to call our event
Protected Overridable Sub OnMyCustomEvent(ByVal e As
MyCustomEventArgs)
RaiseEvent MyCustomEvent(Me, e)
End Sub

End Class

'// A delegate that defines the required
'// method signature
Public Delegate Sub MyCustomEventHandler(ByVal sender As Object, ByVal
e As MyCustomEventArgs)

'// The custom EventArgs you want added
'// to your custom event
Public Class MyCustomEventArgs
Inherits EventArgs

Public Sub New(ByVal myCustomProperty As String)
Me.MyCustomProperty = myCustomProperty
End Sub

Public Property MyCustomProperty() As String
Get
Return _MyCustomProperty
End Get
Set(ByVal value As String)
_MyCustomProperty = value
End Set
End Property
Private _MyCustomProperty As String = String.Empty

End Class
////////////////////

The second (and I think coolest) feature of delegates is the super
easy way to use them for multithreaded solutions. I won't go into
using them with IAsyncCallbacks and the like, so if you'll have to hit
google or msdn for some more in depth samples.

Basically, a delegate exposes a BeginInvoke and EndInvoke method that
can be use to start and end an asynchronous method call. The following
sample will show you how to start a method processing, then perform
some other chores, and finally block until the worker method
completes. This is a very simple example, but can be expanded and
applied to many situations:

////////////////////
Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
Dim worker As New DoTheWorkAsync(AddressOf DoTheWork)

Dim result As IAsyncResult = worker.BeginInvoke("hello,
world", Nothing, Nothing)

'// Do something else while we wait
'// for DoTheWork to finish
Debug.WriteLine("Working...")
System.Threading.Thread.Sleep(1000)
Dim message As String = "the answer to life, the universe, and
everything = {0}"

MsgBox(String.Format(message, worker.EndInvoke(result)))

Me.Text = "Finished!"
End Sub

'// Delegate to use to run our method
'// asynchronously
Private Delegate Function DoTheWorkAsync(ByVal text As String) As
Integer

'// Method to call Asynchronously
Private Function DoTheWork(ByVal text As String) As Integer
System.Threading.Thread.Sleep(2500)

Return 42
End Function
End Class
////////////////////

I hope that helps to explain some of the uses of Delegates a bit
better. Let me know if you need me to clarify anything I said.

Thanks,

Seth Rowe
 
B

Bruce W. Roeser

I'm just studying this too. You know ... this reminds me of the old ANSI
prototype scheme in C way back when ... where you had to declare a
function's "signature" before actually defining the function itself. A
template to enforce the linkage to the actual routine. Right?

-bwr-
 
S

Siegfried Heintze

I wrote the program below twice to teach myself about events and delegates. This is the second version that uses delegates instead of events (but I left the events in delegates).
Are the following statements true for delegates instead of events?
(1) The delegate strategies don't use WithEvents
(2) Delegates must be declared (but so must events so this is a wash)
(3) Delegates don't work with the keyword "handles" and must have a seperate statement where they are added
(4) Delegates require an extra function parameter so we know who to call back
(5) We have to explicitly pass the delegate using the AddressOf feature which I find to be more cryptic than events
(6) Delegates must be called specifically and don't work with the RaiseEvent keyword (I assume, I did not try it)
(7) The delegate syntax gets really painful if you want use the multicast feature, unlike events where you just use the "handles" keyword on multiple functions.

It looks to me like events were invented mostly for VB. In the Case of C#, there is no handy "handles" statement and you have to explicitly add the event in the constructor (typically using the "+=" operator). Also, C# has no "RaiseEvent" keyword so raising an event and calling a delegate are identical.

Now how would I modify this so there could me multiple listener functions called by line 26 (without modifying line 26, of course)?

Thanks,
Siegfried


Imports Microsoft.VisualBasic.DateAndTime

Public Class DelegateTimer

Private mText As New TimerState

'Private WithEvents mText As TimerState = New TimerState

Private Sub mText_UpdateTime(ByVal Jump As Double) 'Handles mText.UpdateTime

lblDisplayTime.Text = Microsoft.VisualBasic.Format(Jump, "##0.00")

Application.DoEvents()

End Sub

Private Sub mText_UpdateTime2(ByVal Jump As Double) 'Handles mText.UpdateTime

System.Threading.Thread.Sleep(100)

End Sub

Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click

Dim d1 As New TimerState.UpdateTimeDele(AddressOf mText_UpdateTime)

Dim d2 As New TimerState.UpdateTimeDele(AddressOf mText_UpdateTime2)

Dim dlgt As TimerState.UpdateTimeDele

dlgt = CType([Delegate].Combine(d1, d2), TimerState.UpdateTimeDele)

mText.TimerTask(dlgt, 9.84)

' mText.TimerTask(9.84)

End Sub

End Class

Class TimerState

'Public Event UpdateTime(ByVal Jump As Double)

Delegate Sub UpdateTimeDele(ByVal Jump As Double)

Public Sub TimerTask(ByVal CallBack As UpdateTimeDele, ByVal Duration As Double)

Dim Start As Double

Dim SoFar As Double

Start = Microsoft.VisualBasic.DateAndTime.Timer

SoFar = Start

Do While Timer < Start + Duration

If Microsoft.VisualBasic.DateAndTime.Timer - SoFar >= 0.1 Then

SoFar = SoFar + 0.1

'RaiseEvent UpdateTime(Timer - Start)

'CallBack.Invoke(Timer - Start)

CallBack(Timer - Start)

End If

Loop

End Sub

End Class
 
S

Siegfried Heintze

I meant to say I left the events in comments, not delegates.

Also, remove "Now how would I modify this so there could me multiple
listener functions called by line 26 (without modifying line 26, of
course)?" as I did that.
 
A

Armin Zingler

Siegfried Heintze said:
I wrote the program below twice to teach myself about events and
delegates. This is the second version that uses delegates instead of
events (but I left the events in delegates).
Are the following statements true for delegates instead of events?
(1) The delegate strategies don't use WithEvents
Right

(2) Delegates must be declared (but so must events so this is a
wash)
(3) Delegates don't work with the keyword "handles" and must have
a seperate statement where they are added

Added to what?
(4) Delegates require an extra function parameter so we know who to
call back

No. The Delegate already knows what to call if you call the delegate. A
delegate does not need function parameters. The signature (number and type
of parameters) of the delegate's and the target must be the same. Can also
be 0.
(5) We have to explicitly pass the delegate using the AddressOf
feature which I find to be more cryptic than events

Events are based on delegates. The target of an event handler must also be
determined by using AddressOf.
(6) Delegates must be called specifically and don't work with the
RaiseEvent keyword (I assume, I did not try it)

Raiseevent internally calls all the delegates attached to the event.
(7) The delegate syntax gets really painful if you want use the
multicast feature, unlike events where you just use the "handles"
keyword on multiple functions.
It looks to me like events were invented mostly for VB.

No. It's an OOP concept.
In the Case
of C#, there is no handy "handles" statement and you have to
explicitly add the event in the constructor (typically using the
"+=" operator).

Right, but a lack of the keyword in C# doesn't say that it has been made for
VB.
Also, C# has no "RaiseEvent" keyword so raising an
event and calling a delegate are identical.

No, events are implemented in the .Net framework. Just the syntax in raising
the event is different.
Now how would I modify this so there could me multiple listener
functions called by line 26 (without modifying line 26, of course)?

I'm not sure what you mean. If the event is declared an you use RaiseEvent,
the event is raised and every event handler is called.



Maybe you think too complicated:
- Events are a concept. Delegates are used to implement the concept.
- Internally, declaring an event means maintaining a list of delegates.
RaiseEvent internally calls all delegates in the list.



"WithEvents" and "Handles" is just and "add-on" but the concepts behind stay
the same. Declaring a WithEvents variable internally creates a property. So,
these two versions are exactly the same:



version A:

Dim WithEvents btnStart As Button

Private Sub btnStart_Click( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnStart.Click

End Sub




version B:

Private _btnStart As Button

Property btnStart() As Button
Get
Return _btnStart
End Get
Set(ByVal value As Button)
If _btnStart IsNot Nothing Then
RemoveHandler _btnStart.Click, AddressOf btnStart_Click
End If
_btnStart = value
If _btnStart IsNot Nothing Then
AddHandler _btnStart.Click, AddressOf btnStart_Click
End If
End Set
End Property


Private Sub btnStart_Click( _
ByVal sender As System.Object, ByVal e As System.EventArgs)

End Sub


WithEvents and Handles just simplify the process of dynamically
adding/removing event handlers to the object currently assigned to a
variable. (and for historic reasons in previous VB versions)


Armin
 
A

Armin Zingler

Some corrections:
No. The Delegate already knows what to call if you call the
delegate. A delegate does not need function parameters. The
signature (number and type of parameters) of the delegate's and the
target must be the same. Can also be 0.

...of the delegate and...
Events are based on delegates. The target of an event handler must
also be determined by using AddressOf.

Should be: An event handler is the target when an event is raised, but it's
address must also be determined by using AddressOf. This is necessary to
create the delegate in order to attach it to the event.


Armin
 
C

CMoya

WithEvents/Handles are just a more "declarative" way to handle events. It's
as simple as that. It's not so much redundant as it is a language feature
(and a very good one). You don't have to worry about removing or tearing
down event handlers... it's all done for you.

When you start actually creating your own custom events in your classes, you
may find that creating delegates that inherit from EventHandler to define
your parameters is helpful. From what I heard long ago, it also helps
performance.
So instead of
Public Event MyCustomEvent(sender As Object, e as System.EventArgs)
You simply do
Public Event MyCustomEvent as EventHandler 'or create your own delegate
based on EventHandler
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top