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" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)...
> 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]" <(E-Mail Removed)> wrote in message
> news:4207ceb6$(E-Mail Removed)...
>> > 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.
>>
>>
>
>