Very basic question, so I'm just looking for a best practice to follow.
My class has a few events which should be subscribed to. (e.g. DiscoveryCompleted). Within the method I do check if the event is null or not, however I'm not sure if I should raise an exception, if so what type. NotImpletementedException?
If the exception is unhandled it doesnt look very elegant.
Your thoughts?
My thought is this is precisely what the NotImplementedException was created for. You should never encounter a NotImplementedException in production code, but it makes it painfully clear during testing that you have a code path that has, well, not been implemented.
Kinda like a TODO comment, but more in-your-face :)
Although, I might question whether having an event handler that must be subscribed to, and not having a default subscriber, doesn't indicate a design issue.
EDIT
I think I misunderstood your initial question slightly, based on your comment. As others have stated (and I questioned), you should not be throwing an exception when you don't have a subscriber to an event handler; simply don't try to call it. If no one cares that event x happened, you can't really do anything about that.
It's not your code's responsibility to care whether anyone cares that it happened, but simply to notify them that it happened if they do care.
EDIT 2 - now with more code
public interface INeedToKnowAboutSomethingImportant
{
void WhenSomethingImportantHappens(SomethingImportantHappenedEventArgs args);
}
public class DoesSomethingImportant
{
private readonly INeedToKnowAboutSomethingImportant _needyDependency;
public DoesSomethingImportant(INeedToKnowAboutSomethingImportant needyDependency)
{
_needyDependency = needyDependency;
}
protected void SomethingImportantHappened(object sender, EventArgs e)
{
//Handle internally
_needyDependency.WhenSomethingImportantHappens(new SomethingImportantHappenedEventArgs(e));
}
}
Following this pattern, you don't have to worry about whether anyone is subscribed to your event handlers. You have to fulfill the dependency, but it doesn't matter AT ALL what you fill it with because whatever it is, it will have that method for you to call.
Events should be optionally subscribed to.
If your class has to call a method, pass a delegate on its constructor instead.
You should not throw NotImplementedException when you check your event. Just check, and execute if not null.
Take for instance. You put an element on your page, but you do not intend to implement any events on the button. The button check for Click event, don't find one, and throws NotImplementedException.
Now that is just wrong.
Event is something that's raised when a certain point the program is hit. Then you can have code that is "triggered" by it. The main path of the code should not be affected whether an event is present or not. If the main path of your code cannot continue without the event being triggered, then you need to use a Method instead.
My suggestion is:
1) Create an event.
2) Subscribe the event with handlers that you are going to implement later.
3) Throw the NotImplementedException in the handler.
As for exception is unhandled, you should never be handling NotImplementedException anyway :P... (And you shouldn't be throwing NotImplementedException for null reference to events).
You should not worry about the event object being null. If no one has subscribed to the event then nothing. If you need another function to run outside of your event raising class, then you need to use another pattern besides the observer pattern. As Eduardo suggested you can pass in a delegate, you might also consider a builder pattern.
I would not throw if an event has no subscribers.
In the "On" method that raises the event you will need a null test (note the race condition prevention). Elsewhere your class should not assume that the event has subscribers.
Related
I have the following code and am wondering how to break it down? It works great but was written by a guru and is over my head. Thank you in advance for any help.
The code basically writes device information sent and received to the GUI. It seems like it has events created based on the device and also invokes GUI stuff.
Why would you need to invoke?
I guess I'm wondering if this is overly complicated or appropriate? What may be a better way to accomplish the same task?
I'm also wondering what the "delegate { };" does?
public event EventHandler CommunicationPerformed = delegate { };
SerialPort _port;
readonly int _delay = 100;
private string ReadAndUpdateStatus()
{
string read = _port.ReadExisting();
CommunicationPerformed?.Invoke(this, new LoaderReadWriteEventArgs(read, LoaderCommunicationDirection.Read));
return read;
}
private void WriteAndUpdateStatus(string data)
{
if (!data.StartsWith("//")) //ignore "Comment" lines but show them on the GUI to read
_port.Write(data);
CommunicationPerformed?.Invoke(this, new LoaderReadWriteEventArgs(data, LoaderCommunicationDirection.Write));
}
public class LoaderReadWriteEventArgs : EventArgs
{
public LoaderCommunicationDirection Direction { get; }
public string Value { get; }
public LoaderReadWriteEventArgs(string value, LoaderCommunicationDirection direction)
{
Value = value;
Direction = direction;
}
}
public enum LoaderCommunicationDirection
{
Read,
Write
}
You asked three questions, and as usual, only one of them got answered. Try to ask only one question in your question.
I'm also wondering what the delegate { } does?
public event EventHandler CommunicationPerformed = delegate { };
As the other answer notes, events are null by default in C#. This technique makes an event handler that does nothing, but is not null.
There are, unfortunately, many syntaxes for an anonymous function in C#. delegate {} means "give me a do-nothing function that matches any non-ref-out formal parameter list that is void returning". That's why people do delegate{}, because it works almost anywhere in a context where an event handler is expected.
I think you need to review this https://learn.microsoft.com/en-us/dotnet/standard/events/.
Why would you need to invoke?
To broadcast to event handlers (any party who registered for this event get notified this way)
I guess I'm wondering if this is overly complicated or appropriate?
*What may be a better way to accomplish the same task?
This is not complicated. This is pretty much as easy as it gets.*
I'm also wondering what the "delegate { };" does?
my two cents.
I dont know which code line you are refering but a delegate is a type that holds a reference to a method. A delegate is declared with a signature that shows the return type and parameters for the methods it references, and can hold references only to methods that match its signature. A delegate is thus equivalent to a type-safe function pointer or a callback. A delegate declaration is sufficient to define a delegate class.
orhtej2 answered your first question quite nicely. Using the explicit Invoke method allows you to leverage the null conditional operator, which reduces the code to fire the event a single line.
As for whether this is overly complicated: No, that's basically how events are done.
What I've sometimes seen (especially in combination with the INotifyPropertyChanged interface in MVVM patterns) are helper methods, which encapsulate the longer, but more obvious pre-C#6 code and let you fire the event with less plumbing.
private void FireCommPerformed(string value, LoaderCommunicationDirection direction)
{
EventHandler handler = CommunicationPerformed;
if (handler != null)
{
handler(this, new LoaderReadWriteEventArgs(value, direction)));
}
}
You could then use it like this:
private string ReadAndUpdateStatus()
{
string read = _port.ReadExisting();
FireCommPerformed(read, LoaderCommunicationDirection.Read);
return read;
}
The Delegate { } is simply an empty delegate, like a null for events. Unless some other method in the code subscribes to the CommunicationPerformed event of this class during runtime, nothing will happen when the event is fired.
Let's focus in on what is exactly happening here. This should help you figure out everything else.
CommunicationPerformed?.Invoke(this, new LoaderReadWriteEventArgs(read, LoaderCommunicationDirection.Read));
This is checking to see if the delegate (event handlers are delegates) (CommunicationPerformed) is null.
Delegates are pointers (but with extra functionality).
If the delegate (pointer) is null, it means that nothing has been assigned to it.
Pointers store memory locations. In this case, it makes a memory reference to the function 'this'. 'This' is a reference to ReadAndUpdateStatus().
So this line basically says: "since the pointer is null, have this pointer reference the ReadAndUpdateStatus() function".
But what about the event args? Well... This is where delegates diverge from pointers.
Delegates don't just safely hold and store memory locations. They also can hold parameters.
You use a class that extends from EventArgs as the way of passing in a list of parameters.
From here, the event handler (event handlers are delegates) CommunicationPerformed will coordinate sending that list of arguments to whatever functions require it.
These functions are called whenever CommunicationPerformed is invoked (e.g. told to run). This is typically indicated with a:
+=CommunicationPerformed(foo,bar)
Now - why would use event handlers (or any delegate - for that matter)?
They're verbose and annoying to read (way more work than writing a simple bool and a trigger function), they don't look like other function, and they're frankly weird - right?
Except that they're really useful. Here's how:
1.) They work a lot like Tasks. You can invoke them in Parallel, in loops, wherever. They keep consistent state. They don't "bleed" and cause bugs.
2.) They're pointers. Guaranteed pass-by-reference. Except, they're magical, and if you stop using the delegate, they won't linger in memory.
3.) They allow you to control state in loops. Sometimes, a bool trigger won't work properly if you're in a really tight loop. You fire an event? Guaranteed behavior that your trigger will only be fired once.
I'm gonna try to answer #1 and #2 (3 is already covered).
#1 - At some point, someone decided that other parts of the program could subscribe to an event that tells them when communication has been performed. Once that decision has been made, it's kind of a "contract". You perform the communication->you fire the event that notifies subscribers that communication has been performed. What those subscribers are doing about that, or why they need to know...Actually not really any of your concern if this class is your focus. In theory, at least. And often that's really practically the case. If your class is doing its job, it's not really your concern who is listening to the events.
#2 - I do think the method of declaring events and event handlers in your code is overly complicated. Plenty of people (and official Microsoft best practices) disagree with me. You can google "why should my event handlers use eventargs" and read plenty on the subject. Or Look here. Another approach is the following:
public event Action<string, LoaderCommunicationDirection> CommunicationPerformed;
void PerformWrite()
{
string myComm = "String I'm sending";
//Line of code that performs communication that writes string here
CommunicationPerformed?.Invoke(myComm, LoaderCommunicationDirection.Write);
}
This is much more succinct than having an entire class that derives from EventArgs. However, it has the very obvious drawback that if you are an event subscriber...you have no idea what string is. Of course, since it's named value in your code...that's not much more helpful. And a comment above the event declaration is just about as useful.
I have event, for example like that:
public event EventHandler<NewReadyMessageEventArgs> NewReadyMessage
The problem is that i need to attach two handlers to it and i need to execute one before another (because the last one depends on first one). I.e. I need certain order of handlers execution.
I understand that in reality handlers will be executed one by one and so I just need to attach them in right order but that would be very error-phrone design.
I want to create separate handler and attach it. In this handler I just want to execute my two handlers in right order. What do you think and what would you suggest?
The problem is that i need to attach two handlers to it and i need to execute one before another (because the last one depends on first one)
In this case, I would rethink your design. It likely makes more sense for the "first" handler to raise its own event.
The second handler could attach to that event, and have the results of both items.
I would not rely on the internal implementation to ensure that the handlers get called in a specific order.
If the handlers can't know about each other but you need them to run in a certain order I would create a "parent" handler that calls the other two handlers in the correct order.
I would suggest implementing your own add implementation if you don't want the default multicast delegate with the default event add/remove implementation.
For more information see http://msdn.microsoft.com/en-us/library/cc713648.aspx
In case it wasn't obvious, if you don't use the default multicast delegate, invocation of subscribers needs to be implemented manually. The above link details how to write custom add/remove to use a multicast delegate. This answer assumes you don't use a multicast delegate For example, something like:
private List<EventHandler> eventList = new List<EventHandler>();
public event EventHandler Event1
{
add { eventList.Add(value); }
remove { eventList.Remove(value); }
}
private void RaiseEvent1()
{
foreach(var e in eventList)
{
e(this, EventArgs.Empty);
}
}
Use a SortedList if you want a specific order...
It sounds like this might be a place where you just need to have multiple (2) events.
If the order is important have two events, and have one that is simply fired right after the other. You can see this at, for example, the page lifecycle in ASP. There are lots of events, and in some cases they're all fired one after the other with thing really inbetween them other than a guarantee that all handlers of the previous event are run. That sounds just like your case here.
I have two events A and B.
I need to check in the event handler of B if the Event A was raised. I know I can do it using a flag but I have used so many flags so far for these kind of situations; and want to use an alternate strategy.
To me this sounds like bad design. If event of A was raised, it should have done something like modifying the state of some object instance. So if event of B is raised, by checking the state changes done by event of A, you should know if it was raised or not. If I am wrong in terms of bad design, then please post more information on your solution.
Example:
void eventOfA(EventArgs args)
{
// modify application or whatever state like
myAppContext.ChangeStatus(2);
// or
myWhateverInstance.DoStuff();
}
void eventOfB(EventArgs args)
{
if(myAppContext.Status == 2)
// eventOfA was raised
else
// eventOfA was not raised
// or
if(myWhateverInstance.DidStuff)
// eventOfA was raised
else
// eventOfA was not raised
}
Maybe you should reconsider the semantic of your events, and create another one.
Say if you have MyApplicationExit and SaveMyData Events, and that you don't need to save everything when application will exit right after, you can indeed check in the SaveMyData Handler wether MyApplicationExit was called before. But a much better choice would be to create another SaveMyDataOnExit event that you send when you are exiting and user want things to be saved. No so much work added since you HAVE to differentiate each case.
All that booleans you need are for Events ? Because if the event handling of .Net doesn't fit you, you might also consider to write your own EventHandler for your custom events, defining the meaning of AddHandler, RemoveHandler and RaiseEvent. So you might create any complex relationship beetwenn events, like raising one event could automatically -or with a condition on the event arg- raise another event, or whatever suits better your needs.
1.st part of the quesion:
What is the difference between these 2 event registrations ?
_popUp.AddHandler(PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(PopUp_PreviewMouseLeftButtonDown));
_popUp.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(_popUp_PreviewMouseLeftButtonDown);
2.nd part of the question:
or eventually versus
popUp.Opened += PopUp_Opened;
According to Redgate's Reflector, there is no difference. Both methods eventually call the internal method EventHandlerStore.AddRoutedEventHandler. This is the reflector output of the add accessor for the PreviewMouseLeftButtonDown event (in the class UIElement):
public void add_PreviewMouseLeftButtonDown(MouseButtonEventHandler value)
{
this.AddHandler(PreviewMouseLeftButtonDownEvent, value, false);
}
As you can see it calls UIElement.AddHandler for you.
Before you edited your question you were asking about the Opened event of the popup. In that case, there is a difference: First, the Opened event is not implemented as a routed event but as a simple event, so you can't even use the AddHandler call on it. Secondly, the reflector shows that a different method is called in the EventHandlerStore which adds the handler to a simple delegate collection.
The important thing might be the AddHandler(xxx,xxx, false).
If you use true then you can catch events that have already been handled, which can be useful if you subclass Controls like TextBox.
Q1:
“The ListControl.OnSelectedIndexChanged method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class.”
A) If I understand the above quote, then if we derive a class from ListControl, we should instead of subscribing to SelectedIndexChanged event, treat OnSelectedIndexChanged() method as an event handler and thus put any event processing logic inside it:
protected override void OnSelectedIndexChanged(
EventArgs e
{
//event handling logic
}
Why would that be better than subscribing to an event(inside .aspx) via OnSelectedIndexChanged = ”name_of_event_handler”?
B)
Anyways, in ascx file we use OnSelectedIndexChanged attribute to attach event handler to an event. Name of this attribute is the same as the name of OnSelectedIndexChanged() method. Why is that? Why isn't instead the name of this attribute SelectedIndexChanged:
<asp:ListControl SelectedIndexChanged = ”name_of_event_handler”
Afterall, attribute refers to an event and not to a method ( OnSelectedIndexChanged() ) that calls this event!
thanx
EDIT:
Hello,
HOWEVER, be sure that you call base.On[EventName] or the event won't fire!
Assuming you don’t want anyone else to be able to respond to this event, then would it be perfectly OK not to call base.On[EventName], since I would think not calling it won’t really do any harm besides not firing an event ( and thus event handlers won't be called )?
I realize some events need to be fired in order for Framework to do its job, but what about not calling base.On[SelectedIndexChanged]?
It is "better" in that:
it is cheaper to use virtual (inheritance) where possible - it removes the need for a few extra objects (delegate instances, etc)
it allows the overriding code to know where it comes in the sequence - i.e. if multiple callers are listening, does it fire first? second? in the middle?
The first point is arguably more important for efficiency, especially in things like controls that have sparse event handlers (i.e. things like EventHandlerList instead of a field-like-event).
I don't really understand the second question, but at a guess: convention.
In general, I prefer to override the On[EventName] functions so that I can control if my logic happens before or after the logic in any subscribers.
HOWEVER, be sure that you call base.On[EventName] or the event won't fire!