473,378 Members | 1,496 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Delegates vs. Events vs. AsyncCallback

LP
Hello!

I am still transitioning from VB.NET to C#. I undertand the basic concepts
of Delegates, more so of Events and somewhat understand AsyncCallback
methods. But I need some clarification on when to use one over another? If
anyone could provide any additional info, your comments, best practices, any
good articles, specific examples, etc.

Thank you
Nov 16 '05 #1
4 22841
see http://blog.monstuff.com/archives/000040.html
"LP" <lp@a.com> wrote in message
news:ub****************@TK2MSFTNGP15.phx.gbl...
Hello!

I am still transitioning from VB.NET to C#. I undertand the basic concepts
of Delegates, more so of Events and somewhat understand AsyncCallback
methods. But I need some clarification on when to use one over another? If
anyone could provide any additional info, your comments, best practices,
any
good articles, specific examples, etc.

Thank you

Nov 16 '05 #2
> I am still transitioning from VB.NET to C#. I undertand the basic concepts
of Delegates, more so of Events and somewhat understand AsyncCallback
methods. But I need some clarification on when to use one over another? If
anyone could provide any additional info, your comments, best practices,
any
good articles, specific examples, etc.


A delegate is nothing more than some syntax around the idea of pointers to
functions, such that the compiler can perform robust type-safety checking on
them. That is, if you say that you want delegate 'D' to hold a pointer to a
function returning void and taking an int parameter, the compiler will
complain if you then try to assign to D a delegate representing a function
returning int and taking an int parameter (or any other conceivable
mismatch, for that matter).

Delegates are enormously handy on their own for situations where you might
want to use one of a number of methods to perform some task, but you won't
know until run-time which method to use. For instance, let's say you're
writing an application that allows users to compare two images by showing
the per-pixel difference between the two images. Of course, there are many
ways you might compute the difference between pixels:

RGB color difference: (R', G', B') = (|R2-R1|, |G2-G1|, |B2-B1|)
brightness difference:
Bright1 = (R1+G1+B1)/3;
Bright2 = (R2+G2+B2)/3;
diff = |Bright2-Bright1|;
(R1',G1',B1') = (diff,diff,diff);

Those are just two; you can no doubt think of many more (show where image 2
is brighter than image 1, redder, whatever, etc.). Without delegates, to
handle this situation you'd have to do something like this:

// compute pixel-difference:
for(int x = 0, x < image.Width; x++)
for(int y = 0; y < image.Height; y++)
{
Color c;
switch(mode)
{
case "rgbdifference"':
c = rgbdiff( Image1.GetPixel(x,y), Image2.GetPixel(x,y) );
case "brightnessdifference":
c = brightnessdiff( Image1.GetPixel(x,y), Image2.GetPixel(x,y) );
etc...
}
result.SetPixel(x,y,c);
}

This is fine, but has the penalty that for every pixel in the images, you
have to evaluate the switch statement. Basically, you're being forced to
decide which method to use every time you want to compare two pixels, rather
than being allowed to decide up-front. With delegates, you can decide
up-front (that is, outside of your loop over all pixels in the images). In
this example, I would make a hash table that stored the delegates so I could
access them by my "mode" variable:

Hashtable h = new Hashtable();
h.Add("rgbdifference", new PixelDiffDelegate(rgbdiff));
h.Add("brightnessdifference", new PixelDiffDelegate(brightnessdiff));
etc...

then later:

PixelDiffDelegate d = h[mode]; // pick the pixel difference method the user
wants.
for(int x = 0, x < image.Width; x++)
for(int y = 0; y < image.Height; y++)
result.SetPixel(x,y, d(Image1.GetPixel(x,y), Image2.GetPixel(x,y)));

Much cleaner code, and faster, too. You can effectively do this same trick
in C and/or C++ with function pointers, but not in a type-safe way.

Events are just a wrapper around the concept of invoking every item in a
list of delegates when some condition happens, with the exception that you
use the "event" keyword when you declare one. The "event" keyword tells the
compiler that, even though under the covers an event is a lot like any other
public method, only the class that declares the event is allowed to call (or
"raise") it. Events, as you're probably aware, are tightly linked to user
interface programming because they're just the thing for responding to user
events. Events are what you want any time you say to yourself "I need X to
happen whenever Y happens, but I have no way of knowing when, exactly, Y is
going to happen." Windows Forms use Events to signal, to anybody who cares,
that various things have happened.

Events make use of delegates because events are allowed to pass data to the
various other pieces of code that have subscribed to the event. If you're
creating a new event, obviously you don't want anybody subscribing to your
event unless they're going to handle the event with a function that's
capable of accepting whatever sort of data you want to pass to them.
Because delegates are type-safe, using them to implement events allows the
compiler to enforce this sort of restriction.

Events are also a total life-saver when you get into multi-threaded
programming (which is pretty much impossible to avoid if you're writing any
sort of interesting WinForms app). There are lots of great resources out on
the web for explaining why you need to use separate threads to perform
long-running operations in WinForms apps. I won't cover that ground again
here; suffice it to say that you'll constantly find yourself in the
situation where you want to run something in its own thread, and then you
need a method of letting the UI know when the thread is done, and thus has
some sort of result, so that the UI can show the results to the user. What
you do in this case is make an event so that the thread can say "Ok, I'm
done", and have the UI subscribe to that event so it can update itself at
the appropriate time. If your operation is _really_ long running, you can
create another event to signal progress, so that the UI can update a
ProgressBar control or something like that. Basically, Events are exactly
what you want to use for communicating safely between threads.

Asynchronous callbacks are very similar to events in terms of what they do.
They both provide a mechanism for one piece of code to say to another "go do
this, and let me know when you're done". The difference is that with an
event, many pieces of code can be notified when the event occurs, whereas
with an async callback, only the caller can be notified. Why? Because
essentially an event, recall, is a wrapper around a list of callbacks. To
subscribe to an event, you use the += operator to subscribe your callback
(that is, your event handler) onto the event object. The event class
handles the grunt-work of invoking all the subscribed callbacks when the
event is raised. Conversely, functions that take an explicit callback
parameter (such as BeginInvoke), don't support any mechanism for handling a
list of callbacks. They just remember the one callback that was passed to
them as a parameter, and then invoke that when they're finished.

So in short:
use Async callbacks if you're sure that you'll only need to notify the code
that called you of completion.
use Events for multi-threading situations, or if you want to enable more
than one piece of code to be notified of the things your code is doing.
use Delegates any time you want simple run-time determination of what method
to use to accomplish some task.

Hope that helps! Sorry that was so long, but this is some tricky stuff. I
remember it took me a while to get my head around it when I was first
learning WinForms/C# programming.
Nov 16 '05 #3
LP
Thanks, great overview!!!

One more question; As far as Events, is it accurate to say that events
internally are implemented as delegates?

Thanks again,

"Jason Black [MSFT]" <ja*****@microsoft.com> wrote in message
news:42********@news.microsoft.com...
I am still transitioning from VB.NET to C#. I undertand the basic concepts of Delegates, more so of Events and somewhat understand AsyncCallback
methods. But I need some clarification on when to use one over another? If anyone could provide any additional info, your comments, best practices,
any
good articles, specific examples, etc.
A delegate is nothing more than some syntax around the idea of pointers to
functions, such that the compiler can perform robust type-safety checking

on them. That is, if you say that you want delegate 'D' to hold a pointer to a function returning void and taking an int parameter, the compiler will
complain if you then try to assign to D a delegate representing a function
returning int and taking an int parameter (or any other conceivable
mismatch, for that matter).

Delegates are enormously handy on their own for situations where you might
want to use one of a number of methods to perform some task, but you won't
know until run-time which method to use. For instance, let's say you're
writing an application that allows users to compare two images by showing
the per-pixel difference between the two images. Of course, there are many ways you might compute the difference between pixels:

RGB color difference: (R', G', B') = (|R2-R1|, |G2-G1|, |B2-B1|)
brightness difference:
Bright1 = (R1+G1+B1)/3;
Bright2 = (R2+G2+B2)/3;
diff = |Bright2-Bright1|;
(R1',G1',B1') = (diff,diff,diff);

Those are just two; you can no doubt think of many more (show where image 2 is brighter than image 1, redder, whatever, etc.). Without delegates, to
handle this situation you'd have to do something like this:

// compute pixel-difference:
for(int x = 0, x < image.Width; x++)
for(int y = 0; y < image.Height; y++)
{
Color c;
switch(mode)
{
case "rgbdifference"':
c = rgbdiff( Image1.GetPixel(x,y), Image2.GetPixel(x,y) );
case "brightnessdifference":
c = brightnessdiff( Image1.GetPixel(x,y), Image2.GetPixel(x,y) );
etc...
}
result.SetPixel(x,y,c);
}

This is fine, but has the penalty that for every pixel in the images, you
have to evaluate the switch statement. Basically, you're being forced to
decide which method to use every time you want to compare two pixels, rather than being allowed to decide up-front. With delegates, you can decide
up-front (that is, outside of your loop over all pixels in the images). In this example, I would make a hash table that stored the delegates so I could access them by my "mode" variable:

Hashtable h = new Hashtable();
h.Add("rgbdifference", new PixelDiffDelegate(rgbdiff));
h.Add("brightnessdifference", new PixelDiffDelegate(brightnessdiff));
etc...

then later:

PixelDiffDelegate d = h[mode]; // pick the pixel difference method the user wants.
for(int x = 0, x < image.Width; x++)
for(int y = 0; y < image.Height; y++)
result.SetPixel(x,y, d(Image1.GetPixel(x,y), Image2.GetPixel(x,y)));

Much cleaner code, and faster, too. You can effectively do this same trick in C and/or C++ with function pointers, but not in a type-safe way.

Events are just a wrapper around the concept of invoking every item in a
list of delegates when some condition happens, with the exception that you
use the "event" keyword when you declare one. The "event" keyword tells the compiler that, even though under the covers an event is a lot like any other public method, only the class that declares the event is allowed to call (or "raise") it. Events, as you're probably aware, are tightly linked to user interface programming because they're just the thing for responding to user events. Events are what you want any time you say to yourself "I need X to happen whenever Y happens, but I have no way of knowing when, exactly, Y is going to happen." Windows Forms use Events to signal, to anybody who cares, that various things have happened.

Events make use of delegates because events are allowed to pass data to the various other pieces of code that have subscribed to the event. If you're
creating a new event, obviously you don't want anybody subscribing to your
event unless they're going to handle the event with a function that's
capable of accepting whatever sort of data you want to pass to them.
Because delegates are type-safe, using them to implement events allows the
compiler to enforce this sort of restriction.

Events are also a total life-saver when you get into multi-threaded
programming (which is pretty much impossible to avoid if you're writing any sort of interesting WinForms app). There are lots of great resources out on the web for explaining why you need to use separate threads to perform
long-running operations in WinForms apps. I won't cover that ground again
here; suffice it to say that you'll constantly find yourself in the
situation where you want to run something in its own thread, and then you
need a method of letting the UI know when the thread is done, and thus has
some sort of result, so that the UI can show the results to the user. What you do in this case is make an event so that the thread can say "Ok, I'm
done", and have the UI subscribe to that event so it can update itself at
the appropriate time. If your operation is _really_ long running, you can
create another event to signal progress, so that the UI can update a
ProgressBar control or something like that. Basically, Events are exactly
what you want to use for communicating safely between threads.

Asynchronous callbacks are very similar to events in terms of what they do. They both provide a mechanism for one piece of code to say to another "go do this, and let me know when you're done". The difference is that with an
event, many pieces of code can be notified when the event occurs, whereas
with an async callback, only the caller can be notified. Why? Because
essentially an event, recall, is a wrapper around a list of callbacks. To
subscribe to an event, you use the += operator to subscribe your callback
(that is, your event handler) onto the event object. The event class
handles the grunt-work of invoking all the subscribed callbacks when the
event is raised. Conversely, functions that take an explicit callback
parameter (such as BeginInvoke), don't support any mechanism for handling a list of callbacks. They just remember the one callback that was passed to
them as a parameter, and then invoke that when they're finished.

So in short:
use Async callbacks if you're sure that you'll only need to notify the code that called you of completion.
use Events for multi-threading situations, or if you want to enable more
than one piece of code to be notified of the things your code is doing.
use Delegates any time you want simple run-time determination of what method to use to accomplish some task.

Hope that helps! Sorry that was so long, but this is some tricky stuff. I remember it took me a while to get my head around it when I was first
learning WinForms/C# programming.

Nov 16 '05 #4
You're welcome! Happy to help.

And yes events are, fundamentally, just delegates; the "event" keyword is
literally just an access modifier that prevents code outside of the class
that declares the event from invoking the event. The functionality around
maintaining a list of subscribers and calling each of them when an event is
raised all comes from the functionality of delegates themselves.

Jessie Liberty provides a much more in-depth explanation of the relationship
between events and delegates in his "Programming C#" book.
"LP" <lp@a.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Thanks, great overview!!!

One more question; As far as Events, is it accurate to say that events
internally are implemented as delegates?

Thanks again,

"Jason Black [MSFT]" <ja*****@microsoft.com> wrote in message
news:42********@news.microsoft.com...
> I am still transitioning from VB.NET to C#. I undertand the basic concepts > of Delegates, more so of Events and somewhat understand AsyncCallback
> methods. But I need some clarification on when to use one over another? If > anyone could provide any additional info, your comments, best
> practices,
> any
> good articles, specific examples, etc.


A delegate is nothing more than some syntax around the idea of pointers
to
functions, such that the compiler can perform robust type-safety checking

on
them. That is, if you say that you want delegate 'D' to hold a pointer
to

a
function returning void and taking an int parameter, the compiler will
complain if you then try to assign to D a delegate representing a
function
returning int and taking an int parameter (or any other conceivable
mismatch, for that matter).

Delegates are enormously handy on their own for situations where you
might
want to use one of a number of methods to perform some task, but you
won't
know until run-time which method to use. For instance, let's say you're
writing an application that allows users to compare two images by showing
the per-pixel difference between the two images. Of course, there are

many
ways you might compute the difference between pixels:

RGB color difference: (R', G', B') = (|R2-R1|, |G2-G1|, |B2-B1|)
brightness difference:
Bright1 = (R1+G1+B1)/3;
Bright2 = (R2+G2+B2)/3;
diff = |Bright2-Bright1|;
(R1',G1',B1') = (diff,diff,diff);

Those are just two; you can no doubt think of many more (show where image

2
is brighter than image 1, redder, whatever, etc.). Without delegates, to
handle this situation you'd have to do something like this:

// compute pixel-difference:
for(int x = 0, x < image.Width; x++)
for(int y = 0; y < image.Height; y++)
{
Color c;
switch(mode)
{
case "rgbdifference"':
c = rgbdiff( Image1.GetPixel(x,y), Image2.GetPixel(x,y) );
case "brightnessdifference":
c = brightnessdiff( Image1.GetPixel(x,y), Image2.GetPixel(x,y) );
etc...
}
result.SetPixel(x,y,c);
}

This is fine, but has the penalty that for every pixel in the images, you
have to evaluate the switch statement. Basically, you're being forced to
decide which method to use every time you want to compare two pixels,

rather
than being allowed to decide up-front. With delegates, you can decide
up-front (that is, outside of your loop over all pixels in the images).

In
this example, I would make a hash table that stored the delegates so I

could
access them by my "mode" variable:

Hashtable h = new Hashtable();
h.Add("rgbdifference", new PixelDiffDelegate(rgbdiff));
h.Add("brightnessdifference", new PixelDiffDelegate(brightnessdiff));
etc...

then later:

PixelDiffDelegate d = h[mode]; // pick the pixel difference method the

user
wants.
for(int x = 0, x < image.Width; x++)
for(int y = 0; y < image.Height; y++)
result.SetPixel(x,y, d(Image1.GetPixel(x,y), Image2.GetPixel(x,y)));

Much cleaner code, and faster, too. You can effectively do this same

trick
in C and/or C++ with function pointers, but not in a type-safe way.

Events are just a wrapper around the concept of invoking every item in a
list of delegates when some condition happens, with the exception that
you
use the "event" keyword when you declare one. The "event" keyword tells

the
compiler that, even though under the covers an event is a lot like any

other
public method, only the class that declares the event is allowed to call

(or
"raise") it. Events, as you're probably aware, are tightly linked to
user

interface programming because they're just the thing for responding to

user
events. Events are what you want any time you say to yourself "I need X

to
happen whenever Y happens, but I have no way of knowing when, exactly, Y

is
going to happen." Windows Forms use Events to signal, to anybody who

cares,
that various things have happened.

Events make use of delegates because events are allowed to pass data to

the
various other pieces of code that have subscribed to the event. If
you're
creating a new event, obviously you don't want anybody subscribing to
your
event unless they're going to handle the event with a function that's
capable of accepting whatever sort of data you want to pass to them.
Because delegates are type-safe, using them to implement events allows
the
compiler to enforce this sort of restriction.

Events are also a total life-saver when you get into multi-threaded
programming (which is pretty much impossible to avoid if you're writing

any
sort of interesting WinForms app). There are lots of great resources out

on
the web for explaining why you need to use separate threads to perform
long-running operations in WinForms apps. I won't cover that ground
again
here; suffice it to say that you'll constantly find yourself in the
situation where you want to run something in its own thread, and then you
need a method of letting the UI know when the thread is done, and thus
has
some sort of result, so that the UI can show the results to the user.

What
you do in this case is make an event so that the thread can say "Ok, I'm
done", and have the UI subscribe to that event so it can update itself at
the appropriate time. If your operation is _really_ long running, you
can
create another event to signal progress, so that the UI can update a
ProgressBar control or something like that. Basically, Events are
exactly
what you want to use for communicating safely between threads.

Asynchronous callbacks are very similar to events in terms of what they

do.
They both provide a mechanism for one piece of code to say to another "go

do
this, and let me know when you're done". The difference is that with an
event, many pieces of code can be notified when the event occurs, whereas
with an async callback, only the caller can be notified. Why? Because
essentially an event, recall, is a wrapper around a list of callbacks.
To
subscribe to an event, you use the += operator to subscribe your callback
(that is, your event handler) onto the event object. The event class
handles the grunt-work of invoking all the subscribed callbacks when the
event is raised. Conversely, functions that take an explicit callback
parameter (such as BeginInvoke), don't support any mechanism for handling

a
list of callbacks. They just remember the one callback that was passed
to
them as a parameter, and then invoke that when they're finished.

So in short:
use Async callbacks if you're sure that you'll only need to notify the

code
that called you of completion.
use Events for multi-threading situations, or if you want to enable more
than one piece of code to be notified of the things your code is doing.
use Delegates any time you want simple run-time determination of what

method
to use to accomplish some task.

Hope that helps! Sorry that was so long, but this is some tricky stuff.

I
remember it took me a while to get my head around it when I was first
learning WinForms/C# programming.


Nov 16 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: STom | last post by:
I have a C# Winforms app that has 5 Winforms, lets say A through E. A: Data entry. When data is entered here in any field, values are updated on forms C, D, E.(Not B) B: Data entry form. When...
3
by: Chua Wen Ching | last post by:
Hi there, I just read Chris Sells's article at http://www.codeproject.com/csharp/delegate_bedtime.asp?df=100&forumid=2983&select=922269#xx922269xx I wonder i can do this: 1) I want to...
10
by: jjkboswell | last post by:
I'm trying to pin down a good naming convention for the 3 things required to implement an event. You need: 1) a delegate 2) an event 3) an event handler Below is my understanding of a...
1
by: CB | last post by:
When designing an object, is there a best practice for how to allow the user of the object to tell the object to remove itself from any delegates / events it has registered with? For example.....
7
by: Peter Larsen [] | last post by:
Hi, I have a problem passing an event in a method call. Please see the following sample: //This class holds information about listeners (in MyEvent). public class First { public event...
1
by: lallous | last post by:
Hello I don't have C++/CLI 2.0 reference handy and the code below was written after long hours of research and shallow readings. From what I see, the code works and looks logical to me. Can you...
5
by: studio60podcast | last post by:
I have been fighting with this for almost two days and I can't figure it out. I'm hoping someone can shed some light on my problem. I have a web user control (NewAccountHolders) that contains a...
1
by: swatisjb | last post by:
hi, need help on basic concept behind indexer,delegates ,events and enum... pls help
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.