C# EventHandler documentation code example - c#

I am reading the .NET documentation on EventHandlers and do not understand this snippet of code from https://learn.microsoft.com/en-us/dotnet/standard/events/ :
class Counter
{
public event EventHandler ThresholdReached;
protected virtual void OnThresholdReached(EventArgs e)
{
EventHandler handler = ThresholdReached;
handler?.Invoke(this, e);
}
// provide remaining implementation for the class
}
What is the purpose of local variable handler? Why not invoke TresholdReached directly TresholdReached?.Invoke(this, e); ?
Similar examples are here:
https://learn.microsoft.com/en-us/dotnet/api/system.eventhandler-1?view=net-5.0

What is the purpose of local variable handler?
Probably none. There is certainly no reason in terms of code-correctness. It appears to be a holdover from the old, pre-null-conditional operator version of the documentation, in which copying the event field ThresholdReached into a local variable was required in order to safely resolve race conditions between raising the event and any other code that might be unsubscribing from it. As you point out, using the null-conditional operator, the code can simply be one line, invoking via the event field itself.
I only say "probably" because I guess there's a very small chance that the author of the documentation was hoping to achieve some other pedagogical goal with the more-explicit form of the code. But I can't imagine what that might be, and it's obviously interfering with general comprehension of the code (i.e. distracting from the important parts).
I submitted a comment on the page to let Microsoft know of the problem. I think there's also probably a place in the Microsoft Git repo where you can submit an issue for the documentation, if you like.
My experience has been that either way the problem is conveyed to Microsoft, they typically fix the problem in relatively short order. I would guess that in the next couple of weeks, that passage will be fixed, and this question will no longer be relevant. :)

Finally, I found the answer almost immediately after posting this question (that bugged me for days).
Reading #lc.'s answer with comments to this questions:
Events - naming convention and style
led me to this page:
https://learn.microsoft.com/en-us/archive/blogs/ericlippert/events-and-races
So the answer is: local handler variable effectively copies the immutable delegate and renders it thread safe.
They could have mention it on that doc page.
EDIT:
See #Peter Duniho answer and comments.

Related

On a code of serial port communication

I have come across the code on another question. It is an answer to the question with C# tag, but I couldn't understand some parts:
using System.Port.IO; ( ? System.IO.Ports)
System.Windows.Timers.Timer serialTimer; (There is no system.windows.timers ?)
serialPort1.DataReceived+=Tab Enter (What's the function of tab and enter here?)
serialPort1.Interval =100; ?
Would you please help me in understanding them?
The link I gave is an answer, not a topic. I am trying to understand what kind of code it is on the link, not to learn how to communicate with a port.
This code was typed by someone without compiling it, and it's full of syntactical and conceptual errors. I'll try to address the lines in your question:
using System.Port.IO; ( ? System.IO.Ports)
Yes, he probably meant to type System.IO.Ports.
System.Windows.Timers.Timer serialTimer; (There is no system.windows.timers ?)
No, there isn't. He either meant a System.Timers.Timer or a System.Windows.Forms.Timer.
serialPort1.DataReceived+=Tab Enter
(What's the function of tab and enter here?)
Those commands (though I usually TabTab) write an empty event handler for you, like:
void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
}
But that is makes little sense here, as his code already shows an event handler for that, so that line should actually read:
serialPort1.DataReceived += serialPort1_DataReceived;
serialPort1.Interval =100; ?
Typo again, he probably meant to set the timer's interval through serialTimer.Interval.
So I think the lesson here is: always assume the worst when you're copypasting someone's code off the web.

C# Handling Events

When I deal set up events, I usually write as such:
data.event += new data.returndataeventhandler(method);
And have a method as such:
void method(parameter)
{
dosomething();
}
This is when the event returns an object.
I have just been reading through somebody elses code and they have used, what seems to be a much cleaner way, as such:
data.ReturnData += delegate(DataSet returnedDataSet)
{
dataset = returnedDataSet;
};
Is there any downfall to this way?
Thanks.
The one major downfall of using anonymous delegates (or the even-cleaner Lambda as suggested by tster) is that you're not going to be able to unsubscribe it from the event later unless you give it some sort of name.
In most cases, this is "No Big Deal (tm)" because the delegate will go away whenever the event source goes away, but this can be a "Subtle Mistake (tm)" if you're subscribing to static events or events on long-lived objects (e.g., the WPF Dispatcher object).
In your case, this doesn't look like a problem at all, so I'd definitely recommend going with tster's recommendation (assuming you're using an appropriately recent version of .Net):
data.ReturnData += returnedDataSet => dataset = returnedDataSet;
(The compiler can infer the type of returnedDataSet from the EventHandler type of ReturnData.)
The primary downfall of using anonymous delegates is that they are not reusable. Other than that there is typically no difference between defining a delegate and then using it elsewhere in your code versus using an anonymous delegate.
One down fall is that it will not appear in your method drop down list. If you do it inline, it should only be simple, nothing overly complex.
Like said by others, the most obvious is not reusable.
Other points:
readability in particular if you have large method body
because .NET generate a random name for anonymous method (not very meaningful or readable) if you use reflection type technology or profiler, it may complicate traceability.
The only downfall is that if you have more than one event it's easier to point it to a method. If you had to attach events in different blocks to the same handler, you would have to store your delegate somewhere so that both blocks could "see" it.
Even cleaner:
data.ReturnData += returnedDataSet => dataset = returnedDataSet;
Nope its just anonymous method thats all.
You can read more about anonymous methods here.
Aside from the other answers of reusablity/Intellisense, I believe the only downfall is if you need to remove the handler later. With a delegate/lamba you cannot easily remove your handler if it no longer needs to be called.

Code-friendly version of event signature in .NET

Preceding posts:
Event Signature in .NET — Using a Strong Typed 'Sender'?
In a C# event handler, why must the “sender” parameter be an object?
Microsoft's conventions and guidelines force .NET users to use special pattern for creating, raising and handling events in .NET.
Event design guidelines http://msdn.microsoft.com/en-us/library/ms229011.aspx state that
Citation:
The event-handler signature observes the following conventions :
The return type is Void.
The first parameter is named sender
and is of type Object. This is the
object that raised the event.
The second parameter is named e and
is of type EventArgs or a derived
class of EventArgs.This is the
event-specific data.
The method takes exactly two
parameters.
These conventions tell developers that the (following) shorter and more obvious code is evil:
public delegate void ConnectionEventHandler(Server sender, Connection connection);
public partial class Server
{
protected virtual void OnClientConnected(Connection connection)
{
if (ClientConnected != null) ClientConnected(this, connection);
}
public event ConnectionEventHandler ClientConnected;
}
and the (following) longer and less obvious code is good:
public delegate void ConnectionEventHandler(object sender, ConnectionEventArgs e);
public class ConnectionEventArgs : EventArgs
{
public Connection Connection { get; private set; }
public ConnectionEventArgs(Connection connection)
{
this.Connection = connection;
}
}
public partial class Server
{
protected virtual void OnClientConnected(Connection connection)
{
if (ClientConnected != null) ClientConnected(this, new ConnectionEventArgs(connection));
}
public event ConnectionEventHandler ClientConnected;
}
Though these guidelines not state why is it so important to follow these conventions, making developers act like monkeys who don't know why and what are they doing.
IMHO, Microsoft's event signature conventions for .NET are bad for your code because they cause additional zero-efficiency effort to be spent on coding, coding, coding:
Coding "(MyObject)sender" casts (not speaking about 99% of situations that don't require sender at all)
Coding derived "MyEventArgs" for the data to be passed inside event handler.
Coding dereferences (calling "e.MyData" when the data is required instead of just "data")
It's not that hard to do this effort, but practically speaking what are we loosing when not conforming to Microsoft's conventions, except that people take you as an heretic because your act of confrontation to Microsoft's conventions verges on blasphemy :)
Do you agree?
The problems you will have:
When you add another argument, you
will have to change your event
handler signature.
When a programmer first looks at
your code, your event handlers will
not look like event handlers.
Especially the latter can waste you far more time than writing a 5 line class.
Regarding having a strongly-typed sender, I've often wondered that myself.
Regarding the EventArgs, I'd still recommend you use an intermediate EventArgs class because you may want to add event information in the future which you don't currently foresee. If you've used a specific EventArgs class all along, you can simply change the class itself and the code where it gets fired. If you pass the Connection as per your example, you'd have to refactor every event handler.
Edit
Jim Mischel made a good point in his comments. By making the sender an object, we enable the same event method to potentially be reused to handle a variety of events. For example, let's say that a grid needs to update itself if:
the user clicks a "refresh" button, or
the system detects that a new entry has been loaded from the server.
You could then say something like this:
serverBus.EntryReceived += RefreshNeededHandler;
refreshButton.Click += RefreshNeededHandler;
...
public void RefreshNeededHandler(object sender, EventArgs args)
{
...
}
Of course, in practice, I have pretty much never had any call for this kind of reuse, whereas the first thing I tend to to in many, many cases is cast the sender to the object type that I know it has to be. If I want to reuse handlers like this, I think it would be easy enough to make two handlers that both call the same convenience method. For me, an event handler is conceptually supposed to handle a specific type of event on a particular group of objects. So I am not personally convinced that the object sender approach is the best convention.
However, I can imagine cases where this would be extremely handy, like if you want to log every event that gets fired.
The biggest problem I see in not following the convention is that you're going to confuse developers who are used to handling events in the way that the runtime library does. I won't say that the convention is good or bad, but it's certainly not evil. .NET developers know and understand how to work with events that are written in conformance with Microsoft's guidelines. Creating your own event handling mechanism on top of that may be more efficient at runtime and might even lead to code that you think is cleaner. But it's going to be different and you'll end up with two event handling "standards" in your program.
My position is that it's better to use a single less-than-ideal standard (as long as it's not horribly broken) than to have two competing standards.
I used strongly typed events (instead of object as it saves me having to cast), it really isn't that hard to understand, "oh look they've used a type that isn't an object"
As for eventArgs, you should use this in case the object changes as per #StriplingWarrior answer.
I don't understand why devs would get confused over it?

Suggest class names for an Event Booking system

I'm writing an Event Booking system in C#, which is vexing me greatly because "event" and "delegate" are reserved words. "Delegate" I've changed to "Attendee", but I can't think of an alternative name for the Event class (and instances thereof). The best I've come up with is "Happening", which is a little bit 1970s for my liking. Plus, the classes will be exposed via a customer API so I have to use professional terminology.
Any suggestions would be most gratefully received.
Edit: it is mainly the naming of instances and parameters that is bothering me:
public Booking CreateBooking(Event event, Person person);
If you really want to use a C# reserved word, you can prefix it with '#'.
E.g.
public class #class
{
...
}
Use with caution...
I would just go with Event. Type names are case-sensitive, so there is a distinction between event and Event. It is (in my humble opinion) the least confusing and most clear solution to the problem.
I would personally just use Event. That doesn't come up as a type name very often. One alternative might be Meeting but it depends on what kind of events you're talking about.
Event really is the right name in the business domain here, for calendars in general.
If you've got recurrent events though, you'll also have exceptions. They're fun - is an EventException an exception to a recurrent event, or a failure to do something with an exception?
None of this can even touch fun with time zones though.
But, event is a keyword, not Event (case sensitivity). Why not use Event? It seems like it is the best name for the job.
C# is case sensitive, why not go with "Event" (capital E)?
Event at thesaurus.reference.com
Or think about using Event and #event.
You could always fall back to old-school naming by pre-pending your classes with a "C" (for Class)
CEvent,CDelegate,CMyClass

The purpose of delegates [duplicate]

This question already has answers here:
Where do I use delegates? [closed]
(8 answers)
Closed 9 years ago.
Duplicate:
Difference between events and delegates and its respective applications
What are the advantages of delegates?
Where do I use delegates?
I wonder what the purpose of delegates is. I haven't used them that much and can't really think of something.
In my courses, it's written that a delegate is a blue-print for all methods that comply with its signature.
Also, you can add multiple methods to one delegate, and then they'll be executed after eachother in the order they were added. Which is probably only usefull for methods that affect local variables or methodes that don't return any values.
I've read that C# implements Events as delegates, which is documented as being:
//Summary: Represents the method that
will handle an event that has no event
data.
//Parameters:
//sender: The source of the event.
//e: An System.EventArgs that contains no event data.
[Serializable]
[ComVisible(true)]
public delegate void EventHandler(object sender, EventArgs e);
Still, it's kinda confusing. Can someone give a good, usefull example of this concept?
Yeah,
You're almost there. A delegate refers to a method or function to be called. .NET uses the Events to say.. when someones presses this button, I want you to execute this piece of code.
For example, in the use of a GPS application:
public delegate void PositionReceivedEventHandler(double latitude, double longitude);
This says that the method must take two doubles as the inputs, and return void. When we come to defining an event:
public event PositionReceivedEventHandler PositionReceived;
This means that the PositionRecieved event, calls a method with the same definition as the
PositionReceivedEventHandler delegate we defined. So when you do
PositionRecieved += new PositionReceivedEventHandler(method_Name);
The method_Name must match the delegate, so that we know how to execute the method, what parameters it's expecting. If you use a Visual Studio designer to add some events to a button for example, it will all work on a delegate expecting an object and an EventArgs parameter.
Hope that helps some...
As you noted a delegate is a way to create a signature for an method call. There are many great examples of using delegates, but the one that really opened my mind is this example.
public delegate Duck GetDuckDelegate();
public GetDuckDelegate GiveMeTheDuckFactoryMethod(string type)
{
switch(type)
{
case "Rubber":
return new GetDuckDelegate(CreateRubberDuck);
case "Mallard":
return new GetDuckDelegate(CreateMallardDuck);
default:
return new GetDuckDelegate(CreateDefaultDuck);
}
}
public Duck CreateRubberDuck()
{
return new RubberDuck();
}
public Duck CreateMallardDuck()
{
return new MallardDuck();
}
public Duck CreateDefaultDuck()
{
return new Duck();
}
Then to use it
public static void Main() {
var getDuck = GiveMeTheDuckFactoryMethod("Rubber");
var duck = getDuck();
}
Arguably, the Factory pattern would be a better method for this, but I just thought up this example on the fly and thought it proved the point of how delegates can be treated as objects
Delegates allow you to pass methods around like values.
For example, .Net has a method called Array.ForEach that takes a delegate and an array, and calls the delegate on each element of the array.
Therefore, you could write,
int[] arr = new int[] { 1, 2, 4, 8, 16, 32, 64 };
Array.ForEach(arr, new Action<int>(Console.WriteLine));
This code will call Console.WriteLine for each number in the array.
There are many things you can do by making functions that take delegates, especially when combined with anonymous methods. For examples, look at LINQ.
Many people initially get confused with the real need for delegates and events. I was one of them and it took me some time to figure it out :-). Recently answered a similar query in ASP.NET forums and thought it would be good if I create a blog post on this topic! Here was the query:
"I was reading an example somewhere of a Bank Class that if the minimum balance is reached you need to inform the rest of the app that the min has reached, but can't we do that by just calling a normal method.
for example: lets say when we deduct some amount from the balance and if minimum reached then call some method to take some action, I am totally missing why do we need delegates and custom events here?"
Thing is in the Bank case, you can definitely call a method, but then it would be simple procedural programming, we need event based programming when we want our code to respond to some events generated by a system.
For eg.: think that windows OS is a system, and we are writing a code (in any language) where we want to capture an event like mouse_click(). Now how would our program know that a mouse click has occured? We can use low level code for it, but since OS is already handling low level code, its best to capture an event raised by the OS.
In other terms, the moment a mouse_click() happens the OS fires an event. The OS doesnt care who captures this event and uses it, it just sends out a notification. Then any code (like ours) can capture that event and use it accordingly. This saves us a lot of time to write code for the same ourselves. And other programs too can use the same event and handle it accordingly.
Similarly, the banking system can be huge, and many other outside applications might be accessing it. The banking system does not know how many such applications there are which need it, or are dependent on it, and how would they handle certain situations like when balance is low, so it simply fires an event whenever low balance occurs, and this event can be used by any other code, besides banking code itself.
Note that each susbcriber to that event can handle that event independently, for eg. the banking code might stop something from executing if balance is low, some other reporting app might send an email in such a case, or some ATM code can stop a particualr transaction and notify the user that balance is low.
Hope this clears things a bit!
I can provide you with an example using a web application architecture:
Generally, with a web application you can provide a front controller that receives requests from many clients. We could put all our methods within the front controller for dealing with the many different types of requests from the clients. However, this get a little cumbersome. Instead we can use delegates to encapsulate functionality for different requests. We could have:
Authentication Delegate
User Management Delegate
and so on. So it's a neat way to split up functionality into logical chunks - delegates. The Struts framework is based on this way of working (the ActionServlet and Action classes).
There are lots of excellent articles explaining delegates - here are some good ones:
Delegates and events
C# Delegates Explained
Delegates in C#
Delegates, to my understanding, provides a way of specializing the behavior of a class without subclassing it.
Some classes have complex generic behavior, but are still meant to be specialized. Think of a Window class in a GUI framework: A Window can propably do a lot on it's own, but you would most likely still want to specialize it in some way. In some frameworks, this is done via inheritance. A different way of doing it is with delegates. Say you want something to happen when the Window resizes: Your delegate class can then implement a method called onWindowResize (provided of course that the Window class supports this), which gets called whenever the Window resizes and is responsible for any specialized behavior when the Window resizes.
I'm not going to argue the merits of delegation over inheritance, but suffice it to say that there are many who feel that delegation is "cleaner" than inheritance.

Categories

Resources