473,725 Members | 2,127 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 22884
see http://blog.monstuff.com/archives/000040.html
"LP" <lp@a.com> wrote in message
news:ub******** ********@TK2MSF TNGP15.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 "brightnessdiff erence":
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("rgbdiffe rence", new PixelDiffDelega te(rgbdiff));
h.Add("brightne ssdifference", new PixelDiffDelega te(brightnessdi ff));
etc...

then later:

PixelDiffDelega te 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.GetPix el(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*****@micros oft.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 "brightnessdiff erence":
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("rgbdiffe rence", new PixelDiffDelega te(rgbdiff));
h.Add("brightne ssdifference", new PixelDiffDelega te(brightnessdi ff));
etc...

then later:

PixelDiffDelega te 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.GetPix el(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 "Programmin g C#" book.
"LP" <lp@a.com> wrote in message
news:%2******** ********@TK2MSF TNGP10.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*****@micros oft.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 "brightnessdiff erence":
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("rgbdiffe rence", new PixelDiffDelega te(rgbdiff));
h.Add("brightne ssdifference", new PixelDiffDelega te(brightnessdi ff));
etc...

then later:

PixelDiffDelega te 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.GetPix el(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
7399
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 data is entered here in any field, values are updated on forms C, D, E (not A). I am considering using delegates to fire events from forms A & B. In forms C, D, E I will have functions with the same signature and even the same name that just...
3
2410
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 built in a class library that had multithreading enabled.
10
17792
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 naming convention based on the Windows Forms events. Can someone let me know if this convention is standard,
1
1740
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.. say we have a static settings class, and it has some OnChange event. The object I am writing will add a method to the settings OnChange event in its constructor. Obviously, at some point, the method needs to be removed from the event so the new...
7
1231
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 EventHandler<EventArgsMyEvent;
1
5851
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 please review it and tell me if I overlooked something. On the other hand, can you suggest a good C++/CLI 2.0 book for starters? Code purpose: To use native EnumWindows() and have its callback handled
5
1598
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 generic list of another web user control (NewAccountHolder). I place NewAccountHolders in a page and all renders properly, but the _lnkRemove_Click never fires when I click "Remove". If I create instances of NewAccountHolder outside of...
1
1249
by: swatisjb | last post by:
hi, need help on basic concept behind indexer,delegates ,events and enum... pls help
0
8752
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9401
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9113
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8097
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6702
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6011
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4519
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4784
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3221
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.