I have a problem where the default delegate does not do enough in some cases. It needs a preamble and a postable. I'm just wondering whether it is better to call a triple delegate
CSELib.ELib eventLib = new CSELib.ELib();
eventLib.Bomb += BombCatcherStart;
eventLib.Bomb += eventLib.BombCatcher;
eventLib.Bomb += BombCatcherEnd;
...
eventLib.BombRaise();
or to call one delegate which then calls the three
void BombCatcherGroup(CSELib.Elib self)
{
BombCatcherStart(self);
self.BombCatcher(self);
BombCatcherEnd(self);
}
CSELib.ELib eventLib = new CSELib.ELib();
eventLib.Bomb += BombCatcherGroup;
...
eventLib.BombRaise();
It basically does the same thing but I just wondering as far as "best practice" is concerned, whether it is better to tell everyone up front as in the triple delegate or to hide it as in in the single delegate.
In the scenario where your operations form a logical chain there aren't really any pros to adding them as individual handlers to the same event - other than that those handlers can be removed down the track. If you don't need/want that, you're incurring the entirely avoidable (if negligible in most scenarios) overhead of additional delegate invocations and losing at least some of the ability to control execution flow. What happens if BombCatcher throws an exception? Easy to handle if all your operations are part of the same method definition; not so easy if you're dealing with separate delegates.
Related
One thing that I find slightly annoying is having to null-check events. An event that has no subscribers is going to be null, so often times code like this has to be written:
MyEvent?.Invoke()
One solution for this problem I've found was this initialization pattern, where we initialize event with a no-op delegate:
public event Action MyEvent = delegate { };
Now, since this event is always going to have at least one dummy subscriber, we no longer have to check for null:
MyEvent.Invoke()
While this is pretty convenient, I was wondering whether this pattern a good practice, or is there some reason that I don't see that would make this a bad decision (aside from having to call an extra dummy subscriber, but I am fine with that)? Thanks.
Is there any point in wrapping event assignments in anonymous async functions?
Lets say this code is in some adapter class:
public event Action<int> someAction;
The following code is in some other class that sets the action:
Example 1:
_someAdapter.someAction += async (someParameter) =>
{
await HandleAction(someParamter);
};
In this case HandleAction has async Task return type.
Example 2:
_someAdapter.someAction += HandleAction;
In this case HandleAction has async void return type.
The same question applies to button click event handlers etc. I have seen examples of both and was wondering why this gets wrapped sometimes. From my testing there doesn't seem to be any difference.
I believe that using an anonymous handler wrapper you'll be able to let the C# Garbage Collector just "unhook" and destroy the handler on this (on example 1) when it is about to be destroyed.
Event handlers outside the this (it isn't the case in your example) would have special attention and wrap it looks a good choice.
If this will live a long time and there is some possibility of you have to hook that event again you should use another strategy to avoid memory leak like ones discussed on this question
The return types differences are related to exception handling and it's ok to use an async void on top-level methods and async event handlers.
I hope it helps.
In your example, there would be likely be no noticeable difference. This is more about coding standards and best practices. In general, it is not recommended that you create 'async void' functions, if you can avoid it. The purpose of that feature is to allow async code in functions that can't change their signature (like overrides). An 'async void' function has disadvantages like swallowing exceptions and being less composable.
If, for instance, you wanted to call HandleAction from another place/method (often this is the reason for using a named method instead of an anonymous function), you would not be able to await it unless it returns Task.
Also, if HandleAction threw an exception, you would not be able to catch it if you can't await it, so you better be sure it will handle all exceptions internally.
I won't recommend to use an anonymes delegate as an event handler. The reason is that it might come to cycling references and thus the garbage collector won't be able to free up memory - so called memory leak.
Especially in the Xamarin-world, where the managed garbage collector often won't know the real size of an object, developers should have an eye on memory and allocations their applications needs.
By avoiding anonymes delegates you are able to break the cycle simple by removing the event handler assignment.
I can't comment on your adapter handlers, but... seeing as you say "The same question applies to...", the answer might be the same as for button click event handlers, etc, which is (arguably the largest benefit of async in UI applications) - you get to perform expensive async operations in the handlers off the UI thread.
E.g.
_button.Click += async (...) =>
{
int answer = await ExpensiveHttpResultThatTakes10Seconds();
_answer.Text = answer.ToString();
};
If that wasn't async, the UI would freeze up for 10 seconds, not responding to clicks, keys, etc.
Because it is async, the UI remains responsive during those 10 seconds, as the await is non-blocking, processing UI events and even other event handlers.
From the content of the answer to this question I learned a new trick; to add a trivial handler to an event in order to avoid null checking when it is raised.
public static event EventHandler SomeEvent = delegate {};
and to invoke it without the null checking:
SomeEvent(null,EventArgs.Empty);
Does this add significant overhead? If not, why isn't something like this built in?
Does this add significant overhead? If not, why isn't something like this built in?
It doesn't add significant overhead - merely a delegate call when the event is raised.
As for why it's not built-in - there are a couple of downsides:
This isn't necessarily bullet proof - you can still clear the handler list afterwards, in which case, you'd still need the proper checking.
This does add overhead - while minor, that overhead could be problematic in specific scenarios.
I have seen some people leaning on handing methods to callbacks/events and then sometimes just handing them lambdas.
Can anybody speak to any difference between the two? I would have originally thought them to be the same, but the inconsistency I have seen implemented sometimes makes me wonder if there is a case where one is preferable over the other? Obviously if there is a very large ammount of code it shouldn't be an on the spot lambda, but otherwise..
Can you all outline any differences between the two if any, and outline the rules you use in choosing between the two when both are available?
One of the biggest differences between the two is the ease by which you can unsubscribe from the event. With the method based approach unsubscribing is a simple operation, simply use the original method
m_button.Click += OnButtonClick;
...
m_button.Click -= OnButtonClick;
With lambdas this is not as simple. You must store away the lambda expression and to be used later on to unsbuscribe from the event
m_button.Click += delegate { Console.Write("here"); }
...
// Fail
m_button.Click -= delegate { Console.Write("here"); }
EventHandler del = delegate { Console.Write("here"); }
m_button.Click += del;
...
m_button.Click -= del;
It really detracts from the convenience of using lambda expressions.
In most languages that have lambdas (including C#), creating a lambda inside a method creates a closure -- that is, the local variables inside the declaring method will be visible to the lambda. That's the biggest difference i'm aware of.
Aside from that, unless you name your event handler somehow, in a way that's accessible in another function, you'll find it hard to detach the event handler later. This is doable by storing the delegate in an instance- or class-level variable, but it can be kinda ugly.
The biggest reason for using a Lambda is to have delayed execution, i.e. you define the operations you want to perform, but you won't have the parameters until later. You generally don't use lambdas for events and callbacks; you use anonymous methods.
Using anonymous methods for events and callbacks is okay for simple events that you don't need to unsubscribe to. The biggest determining factor for me is where I'm declaring it. I'm not going to declare an event handler for a form as an anonymous method, but if I have a short-lived need to connect to an event, it might be okay.
In general, I use actual methods for callbacks and events more than anonymous methods; the events I'm handling are tied to the lifetime of the object, not the lifetime of the method, and I find that it's clearer in code to have callbacks clearly defined external to the function that hooks them up. Some of that is personal preference.
In most cases, there is little practical difference. Which one to use is mainly a matter of personal preference (i.e. what you want the code to look like). In some cases, there are some practical reasons to prefer one over the other:
As noted in the accepted answer, unsubscribing an anonymous method is more complex than unsubscribing a named method. Without a name, there's no way to refer to the anonymous method except by the delegate instance created at runtime where the anonymous method is declared. Using a named method, the delegate can be unsubscribed without having retained a reference to the original delegate (or its equivalent).
On the other hand, a reason to prefer a lambda expression is when the handler for the event is an implementation detail unique to the named method in which the lambda/anonymous method is declared. This can help keep such implementation details private and local to the method where they are used.
Another reason one might use a lambda expression is if there's a need to "adapt" the delegate type. I.e. you do want to call a named method to handle the event, but that method has a different signature than that required by the event. This might be the case where you want to reuse the method for different events or other situations, where some of the parameters from the event might not be applicable. Another case might be where you want to introduce a new parameter a value for which the event might not provide (e.g. an index for a collection of objects all having the same event you want to subscribe to).
There is one special case that may sometimes come up, which is the choice of whether to use a named method by itself, or to use an anonymous method that then calls that named method. It is important to note that, in absence of other practical reasons for choosing one over the other, using a named method is marginally more efficient in this particular case, because it removes one method call from the invocation. In practice, you'll probably never notice the difference, but it's just overhead so if there's no specific, practical reason to incur it, one should probably avoid it, i.e. subscribe the named method directly.
I've got the following (simplified):
interface IFindFilesObserver
{
void OnFoundFile(FileInfo fileInfo);
void OnFoundDirectory(DirectoryInfo directoryInfo);
}
class FindFiles
{
IFindFilesObserver _observer;
// ...
}
...and I'm conflicted. This is basically what I would have written in C++, but C# has events. Should I change the code to use events, or should I leave it alone?
What are the advantages or disadvantages of events over a traditional observer interface?
Consider an event to be a callback interface where the interface has only one method.
Only hook events you need
With events, you only need to implement handlers for events you're interested in handling. In the observer interface pattern, you'd have to implement all methods in the entire interface including implementing method bodies for notification types you don't actually care about handling. In your example, you always have to implement OnFoundDirectory and OnFoundFile, even if you only care about one of these events.
Less maintenance
Another good thing about events is you can add a new one to a particular class so that it will raise it, and you don't have to change every existing observer. Whereas if you want to add a new method to an interface, you have to go around every class that already implements that interface and implement the new method in all of them. With an event though, you only need to alter existing classes that actually want to do something in response to the new event you're adding.
The pattern is built into the language so everybody knows how to use it
Events are idiomatic, in that when you see an event, you know how to use it. With an observer interface, people often implement different ways of registering to receive notifications and hook up the observer.. with events though, once you've learnt how to register and use one (with the += operator), the rest are all the same.
Pros for interfaces
I haven't got many pros for interfaces. I guess they force someone to implement all methods in the interface. But, you can't really force somebody to implement all those methods correctly, so I don't think there's a lot of value on this.
Syntax
Some people don't like the way you have to declare a delegate type for each event. Also, standard event handlers in the .NET framework have these parameters: (object sender, EventArgs args). As sender doesn't specify a particular type, you have to down-cast if you want to use it. This often is fine in practice, it feels not quite right though because you're losing the protection of the static type system. But, if you implement your own events and don't follow the .NET framework convention on this, you can use the correct type so potential down-casting isn't required.
Hmm, events can be used to implement the Observer pattern. In fact, using events can be regarded as another implementation of the observer-pattern imho.
Events are harder to propagate through chain of objects, for example if you use FACADE pattern or delegate work to other class.
You need to be very careful with unsubscribing from events to allow object to be garbage collected.
Events are 2x time slower than simple function call, 3x slower if you do null check on every raise, and copy event delegate before null check and invocation to make it thread safe.
Also read MSDN about new (in 4.0) IObserver<T> interface.
Consider this example:
using System;
namespace Example
{
//Observer
public class SomeFacade
{
public void DoSomeWork(IObserver notificationObject)
{
Worker worker = new Worker(notificationObject);
worker.DoWork();
}
}
public class Worker
{
private readonly IObserver _notificationObject;
public Worker(IObserver notificationObject)
{
_notificationObject = notificationObject;
}
public void DoWork()
{
//...
_notificationObject.Progress(100);
_notificationObject.Done();
}
}
public interface IObserver
{
void Done();
void Progress(int amount);
}
//Events
public class SomeFacadeWithEvents
{
public event Action Done;
public event Action<int> Progress;
private void RaiseDone()
{
if (Done != null) Done();
}
private void RaiseProgress(int amount)
{
if (Progress != null) Progress(amount);
}
public void DoSomeWork()
{
WorkerWithEvents worker = new WorkerWithEvents();
worker.Done += RaiseDone;
worker.Progress += RaiseProgress;
worker.DoWork();
//Also we neede to unsubscribe...
worker.Done -= RaiseDone;
worker.Progress -= RaiseProgress;
}
}
public class WorkerWithEvents
{
public event Action Done;
public event Action<int> Progress;
public void DoWork()
{
//...
Progress(100);
Done();
}
}
}
Pros of an interface-solution:
If you add methods, existing observers needs to implement those methods. This means that you have less of a chance of forgetting to wire up existing observers to new functionality. You can of course implement them as empty methods which means you have the luxury of still doing nothing in response to certain "events". But you won't so easily forget.
If you use explicit implementation, you'll also get compiler errors the other way, if you remove or change existing interfaces, then observers implementing them will stop compiling.
Cons:
More thought has to go into planning, since a change in the observer interface might enforce changes all over your solution, which might require different planning. Since a simple event is optional, little or no other code has to change unless that other code should react to the event.
Some further benefits of events.
You get proper multicast behaviour for free.
If you change the subscribers of an event in response to that event the behaviour is well defined
They can be introspected (reflected) easily and consistently
Tool chain support for events (simply because they are the idiom in .net)
You get the option to use the asynchronous apis it provides
You can achieve all of these (except the tool chain) yourself but it's surprisingly hard. For example:
If you use a member variable like a List<> to store the list of observers.
If you use foreach to iterate over it then any attempt to add or remove a subscriber within one of the OnFoo() method callbacks will trigger an exception unless you write further code to deal with it cleanly.
The best way to decide is this: which one suits the situation better. That might sound like a silly or unhelpful answer, but I don't think you should regard one or the other as the "proper" solution.
We can throw a hundred tips at you. Events are best when the observer is expected to listen for arbitrary events. An interface is best when the observer is expected to listed to all of a given set of events. Events are best when dealing with GUI apps. Interfaces consume less memory (a single pointer for multiple events). Yadda yadda yadda. A bulleted list of pros and cons is something to think about, but not a definitive answer. What you really need to do is try both of them in actual applications and get a good feel for them. Then you can choose the one that suits the situation better. Learn form doing.
If you have to use a single defining question, then ask yourself which better describes your situation: A set of loosely related events any of which may be used or ignored, or a set of closely related events which will all generally need to be handled by one observer. But then, I'm just describing the event model and interface model, so I'm back at square one: which one suits the situation better?
Pros are that events are more 'dot-netty'. If you are designing non-visual components that can be dropped onto a form, you can hook them up using the designer.
Cons are that an event only signifies a single event - you need a separate event for each 'thing' that you want to notify the observer about. This doesn't really have much practical impact except that each observed object would need to hold a reference for every observer for every event, bloating memory in the case where there are lots of observed objects (one of the reasons they made a different way of managing the observer/observable relationship in WPF).
In your case I'd argue it doesn't make much difference. If the observer would typically be interested in all those events, use an observer interface rather than separate events.
I prefer an event base solution for the following reasons
It reduces the cost of entry. It's much easier to say "+= new EventHandler" than to implement a full fledged interface.
It reduces maintenance costs. If you add a new event into your class that's all that needs to be done. If you add a new event to an interface you must update every single consumer in your code base. Or define an entirely new interface which over time gets annoying to consumers "Do I implement IRandomEvent2 or IRandomEvent5?"
Events allow for handlers to be non-class based (ie a static method somewhere). There is no functional reason to force all event handlers to be an instance member
Grouping a bunch of events into an interface is making an assumption about how the events are used (and it's just that, an assumption)
Interfaces offer no real advantage over a raw event.
Java has language support for anonymous interfaces, so callback interfaces are the thing to use in Java.
C# has support for anonymous delegates - lambdas - and so events are the thing to use in C#.
A benefit of interfaces is that they are easier to apply decorators to. The standard example:
subject.RegisterObserver(new LoggingObserver(myRealObserver));
compared to:
subject.AnEvent += (sender, args) => { LogTheEvent(); realEventHandler(sender, args); };
(I'm a big fan of the decorator pattern).
If your objects will need to be serialized in some way that retains references such as with NetDataContractSerializer or perhaps protobuf events will not be able to cross the serialization boundary. Since observer pattern relies on nothing more than just object references, it can work with this type of serialization with no problem if that is what is desired.
Ex. You have a bunch of business objects that link to each other bidirectionally that you need to pass to a web service.