Explicit Event add/remove, misunderstood? - c#

I've been looking into memory management a lot recently and have been looking at how events are managed, now, I'm seeing the explicit add/remove syntax for the event subscription.
I think it's pretty simple, add/remove just allows me to perform other logic when I subscribe and unsubscribe? Am I getting it, or is there more to it?
Also, while I'm here, any advice / best practices for cleaning up my event handles.

The add/remove properties are basically of the same logic of using set/get properties with other members.
It allows you to create some extra logic while registering for an event, and encapsulates the event itself.
A good example for WHY you'd want to do it, is to stop extra computation when it's not needed (no one is listening to the event).
For example, lets say the events are triggered by a timer, and we don't want the timer to work if no-one is registered to the event:
private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
private EventHandler _explicitEvent;
public event EventHandler ExplicitEvent
{
add
{
if (_explicitEvent == null) timer.Start();
_explicitEvent += value;
}
remove
{
_explicitEvent -= value;
if (_explicitEvent == null) timer.Stop();
}
}
You'd probably want to lock the add/remove with an object (an afterthought)...

Yes, the add/remove syntax allows you to implement your own subscription logic. When you leave them out (the standard notation for an event) the compiler generates standard implementations. That is like the auto-properties.
In the following sample, there is no real difference between Event1 and Event2.
public class Foo
{
private EventHandler handler;
public event EventHandler Event1
{
add { handler += value; }
remove { handler -= value; }
}
public event EventHandler Event2;
}
But this is a separate topic from 'cleaning up' handlers. It is the subscribing class that should do the unsubscribe. The publishing class can not help with this very much.
Imagine a class that would 'clean' up the subscription list of its events. It can only sensibly do this when it is Disposed itself, and then it is unlikely to be productive as a Disposed class usually becomes collectable shortly after it is Disposed.

Add/remove syntax is commonly used to "forward" an event implementation to another class.
Cleaning up subscriptions (not "event handles") is best done by implementing IDisposable.
UPDATE: There is some variation on which object should implement IDisposable. The Rx team made the best decision from a design perspective: subscriptions themselves are IDisposable. Regular .NET events do not have an object that represents the subscription, so the choice is between the publisher (the class on which the event is defined) and the subscriber (usually the class that contains the member function being subscribed). While my design instincts prefer making the subscriber IDisposable, most real-world code makes the publisher IDisposable: it's an easier implementation, and there may be cases where there isn't an actual subscriber instance.
(That is, if the code actually cleans up event subscriptions at all. Most code does not.)

Related

Anonymous event handlers and disposing

I have a rather short question about anonymous event handlers:
This is the code that I have:
public void AddTestControl(Control ctrl)
{
ctrl.Disposed += (o, e) => { RemoveTestControl(ctrl); };
ctrl.SomeEvent += _Control_SomeEvent;
}
public void RemoveTestControl(Control ctrl)
{
ctrl.SomeEvent -= _Control_SomeEvent;
}
Is this code above fine, or should the code be rewritten in order to remove the Disposed Event Handler?
Something like this:
public void AddTestControl(Control ctrl)
{
ctrl.Disposed += _Control_Disposed;
ctrl.SomeEvent += _Control_SomeEvent;
}
public void RemoveTestControl(Control ctrl)
{
ctrl.Disposed -= _Control_Disposed;
ctrl.SomeEvent -= _Control_SomeEvent;
}
Generally, the only situation where you need to remove the event handlers from an object in order for it to be eligible for garbage collection is when the publisher object (the one defining the event) lives longer than the subscriber object (the one containing the event handlers). In such a situation the GC won't be able to release the subscriber when it goes out of scope since it's still being referenced by the publisher.
In this case, assuming this is WebForms or WinForms, the publisher (that is the Control object), is most likely a child object of the subscriber (probably a Page or a Form), which will be the first to go out of scope taking all its associated objects with it. Hence there's no need to remove the event handlers.
It always feels cleaner to me to unsubscribe from events, even in situations where I know the subscribers always outlive the publisher (the object raising the event): the event will never be raised again, the publisher is no longer reachable and can be collected.
Then again, how many people go to the trouble of unsubscribing every event handler in e.g. a WinForms application? The object references point from the publisher to the subscribers, not the other way around, so the publisher can be collected while the subscribers live on. It doesn't present the same danger as the opposite situation, where a long-lived publisher (e.g. a static event) can wastefully keep potentially large subscribers alive long after they could have been collected.
If you want/need to unsubscribe, then the requirement to unsubscribe the same delegate makes anonymous event handlers a bit of a pain. The Reactive Extensions solve this problem in a neat way: rather than having to remember the delegate you subscribed, subscribing returns an IDisposable which unsubscribes when disposed. Chucking all your subscriptions into a CompositeDisposable lets you unsubscribe everything with just one Dispose call.
Both codez are fine, but I like second as a matter of personal preference. It reads clearer than the first.
On top of it with the first code, there's anonymous lambda delegate and it gets a current reference to ctrl. That code may behave unexpectedly depending on situation and compile optimisation settings: whether or not the call is inlined or not.
Not to mention that there's architectural problem with the code: you have ControlOwner and a bunch of Child Controls. I take it you're adding child controls to ControlOwner at runtime, and then trying to react to their behavivour by subscribing ControlOwner to the childControl events. This is fine for events like _ButtonClicked etc. But not good for Dispose. Let the child control handle it's disposing on itself, the OwnerControl doesn't need to know about it. Not to mention that it may not exist at a time ChildControl[n].Dispose is called.
In short:
* it is better to leave dispose event on ChildControl alone and do all clean up in ChildControl.Dispose
* it is not necessary to unsubscribe from events. Event dispatcher will check if subscriber is alive.

Do I use a delegate or an event

I have a Connection class which reads packets (commands) from a text stream and then distributes the commands to a set of handlers which process the commands as they see fit.
Eg.. Connection class reads in a command "HELLO" and then passes the command off to the handlers, where one or more handler may do something useful with the HELLO command.
Right now I use a delegate called HandleCommand which all command handlers must adhere to in order to receive the commands.
The question is, would it be more logical to use an event (eg.. CommandReceived) which the handlers could individually subscribe to? I'm having a hard time weighing up the pros and cons. it seems more wasteful to make it an event, because then an EventArgs class has to be generated for each command received.
In contrast, there is also a DisconnectCallback delegate which I strongly believe would be better as an event and will probably change.
Thank you
It seems your distributor now has to keep a list of handlers (class or delegates). That means you are duplicating the functionality of event.
The situation seems to call for events. It would decouple the components.
Concerning the 'wastefulness' of events and eventargs, see this question and stop worrying.
First - until you have evidence that it's a performance bottleneck, don't sacrifice clarity. The GC is fast and it's unlikely cleaning up a short-lived eventargs class will be the dominating performance factor here.
Anyway, If the consumers are only going to read and not modify the data, I'd make it an event. Otherwise you'd probably want to make an interface for a 'filter' that can read and modify, and pass the new value to the next one.
Events would be the most obvious approach as there are more than one command handlers.
I'm curious as to how command handlers "adhere" to a connection using delegates. You have to either simulate the event behavior by using a list of listeners or the command must actively call the handlers, what indeed compromises decoupling.
You are not required to use EventHandler or EventHandler<T> when creating an event, even though that is against Microsoft's recomendation. You can use your current delegate as the datatype for the event like so:
public event MyDelegateType EventName;
Edit:
If you are concerned about performance you can use an EventHandlerList class like so:
private EventHandlerList _events = new EventHandlerList();
private static object MyDelegateKey = new object()
public event MyDelegate EventName {
add {
_events.AddHandler(MyDelegateKey, value);
}
remove {
_events.RemoveHandler(MyDelegateKey, value);
}
}

Pitfalls of Event Handling in Java

I'm working on a program that needs a Java object to have an event. I'm quite familiar with how this works in C#, having had enough experience to learn the pitfalls.
What are the pitfalls of working with events in Java? How are they different from events in C# 2.0?
Example: An object changed event to prompt a save from the owner object.
Note: Java 1.5
Related: C# event handling (compared to Java)
Java has no built-in concept of events, so you are best off using variations of The Observer Pattern.
In C#, you're supposed to do like this when you fire an event:
public event SomeDelegate MyEvent;
private void FireMyEvent(MyEventArgs args)
{
var deleg = MyEvent;
if (deleg != null) deleg(args);
}
... to protect yourself from concurrent modification (in case a thread removes an event listener between you checking the nullness of MyEvent and calling it). In Java, you'd use a CopyOnWriteArrayList instead to protect yourself from concurrent modification:
private final CopyOnWriteArrayList<MyEventListener> listeners =
new CopyOnWriteArrayList<MyEventListener>();
private void fireMyEvent(MyEventArgs args){
// Iteration is performed over a snapshot of the list, concurrent
// modifications from other threads are invisible to the iterator
// and will not cause ConcurrentModificationExceptions.
for (MyEventListener listener : listeners)
listener.eventOccurred(args);
}
As mentioned earlier, Java doesn't have delegates and events that C# has. But considering it's a "generalized" implementation of the Observer pattern (GoF) you can implement it on your own.
There are examples in the wikipedia page on how to implement the pattern with java.util.Observable and java.util.Observer. The general idea is to let classes that implement Observer to subscribe themselves to an Observable class.
I usually roll my own implementation since it is darn easy to do so, as you only need to make an interface declaring the methods that the "observable" class call to it's registered "observers". Here is a simple example of an observable class that can register SimpleObserver objects and perform some kind of event on them:
public class MyObservableClass {
List<SimpleObserver> observers = new ArrayList<SimpleObserver>();
/**
* Registers the observer
*/
public void addObserver(SimpleObserver observer) {
observers.add(observer);
}
/**
* Removes the registered observer (to be nice towards the
* garbage collector).
*/
public void removeObserver(SimpleObserver observer) {
observers.remove(observer);
}
/**
* Notifies the observers with the given data
*/
private void notifyObservers(String data) {
for(SimpleObserver o : observers) {
o.onEvent(data);
}
}
public void doSomething() {
// Do some stuff
String data = "Waffles and pwnies";
// Notify the observers that something happened.
notifyObservers(data)
}
}
…and here is the simple observer interface.
public interface SimpleObserver {
void onEvent(String data);
}
This may seem a bit complex, but the benefit is that the Observable class doesn't need to know what exact other objects are "listening" to it (which is why observers are sometimes called listeners). It provides a clean separation of concerns between them both. The Observers need to register themselves to an observable.
The only "gotcha" that I can think of is that of a memory leak that this pattern may cause even in a memory managed environment such as Java. This is because of the "reference islands" between Observers and Observables which will confuse the garbage collector and not attempt to remove the objects from memory. It is always a good idea to remove unused observers.
Java doesn't have a dedicated concept of Event. It's implemented through APIs along the lines of Observable + Observer. As far as I know, there is no dedicated lambda-functer API in the Java specification.
Events are strictly container specific in Java, and the standard library merely provides a generalized interface (which is typically extended for specific requirements).
The only 'gotcha' regarding events that can arguably be considered in context of Java (in general) is in Swing containers (Component) and event dispatching. The swing framework is single-threaded and you are expected to not use the event dispatch thread (i.e. the call back) to do computationally intensive/high-latency work in the event listener.

c# class instance communication

When you have different instances of the same class such as 'FootballTeam' for example and you want to let another instance of this FootballTeam class know that something occured, whats the best way to go about this?
Events won't really work I guess...
EG:
FootballTeam A = new FootballTeam();
FootballTeam B = new FootballTeam();
// now A needs to let B know about it's manager change
// manager is a property inside this class...
Events could work:
FootballTeam A = new FootballTeam();
FootballTeam B = new FootballTeam();
A.ManagerChanged += B.OnOtherManagerChanged;
Definition of the event -- FootballTeam calls its OnManagerChanged method when its Manager property changes value:
class FootballTeam
{
public event EventHandler ManagerChanged;
protected virtual void OnManagerChanged(EventArgs e)
{
EventHandler handler = ManagerChanged;
if (handler != null)
handler(this, e);
}
public void OnOtherManagerChanged(object sender, EventArgs e)
{
FootballTeam otherTeam = (FootballTeam) sender;
// A manager changed on a different FootballTeam instance
// ...do something here
}
}
There are a lot of responses to this question that provide examples of how to solve this type of problem using events (or the Observer pattern). And while these are appropriate patterns to employ, choosing how and when to use them can have a significant impact on the end result.
In your example, you describe FootballTeam instances that need to be informed when relevant changes in other instances take place. However, you must decide whether it should really be the responsibility of the FootballTeam class to both listen for and respond to such events. The Single Responsibility Principle states that there should be only one reason for a class to change. Adhering to this design concept generally results in clearer separation of concerns and overall better code.
There are a number of problems that can arise in such a design.
First, having each FootballTeam be responsible for listening for changes and responding to them can quickly become problematic. For one thing, the number of direct (point-to-point) communication lines between FootballTeam instances grows with the square of the number of instances: n*(n-1). With five teams you would have 20 connections, with ten teams you would have 90, with thirty teams you would have 870.
Managing the event subscriptions (and unsubscription) for all these instances is likely to result in confusing and unmaintainable code. Also, having event subscriptions between each pair of teams can have affect garbage collection - and result in potential leaks - or in the very least, instances of objects staying in memory much longer than needed.
Another potential problem with a design where all instances subscribe to events on each other, is infinite or cyclical event chains: A notifies B, which updates itself and notifies C, which updates itself and notifies A, which updates itself and notifies B ... ad infinitum. Or until you run out of stack space. This can be a difficult problem to solve in such a design, and would likely require awkward state management to prevent cycles and recursion.
An alternative approach, is to create a separate observer class - let's call it FootballTeamObserver - that subscribes to the change events of all FootballTeam instances, and would responsible for propagating changes, as necessary, across instances. So FootballTeam would still be responsible for broadcasting when a meaningful change takes place, and FootballTeamObserver would respond to the notification. Importantly, there would ever only be once instance of FootballTeamObserver - the singleton pattern - ensuring that a central handling site exists for all notification. This both reduces the number of event subscriptions (which would only be as many as there are teams) and separates the responsibility of responding to changes in a clean way. It can also be responsible for cycle detection and making sure that update chains have a finite length.
The typical way to do this in .Net is to define an event for operations that are interesting to other objects. For instance you might define the following
public class FootballTeam {
private string _manager;
public string Manager {
get { return _manager; }
set {
if ( ManagerChanged != null ) {
ManagerChanged(this,EventArgs.Empty);
}
}
}
public event EventHandler ManagerChanged;
}
Ideally you'd want a more type safe event but there's only so much space here
You can then listen to this event in other FootballTeam instances and respond to that event.
FootballTeam a = new FootballTeam();
FootballTeam b = new FootballTeam();
a.ManagerChanged += (sender, e) => {
Console.WriteLine("A's manager changed");
};
There are a few different ways. The fact that you need to do this is sometimes indicative of a design problem, though of course pragmatism must come into play.
One simple way is to have a private static event in the FootballTeam class which itself subscribes to in the ctor:
public class FootballTeam
{
private static event EventHandler SomethingHappened;
public FootballTeam()
{
SomethingHappened += this.HandleSomethingHappened;
}
public void DoSomething()
{
SomethingHappened(); //notifies all instances - including this one!
}
}
To avoid a memory leak, make sure to clean up the event handlers by implementing IDisposable:
public class FootballTeam : IDisposable
{
//...
public void Dispose()
{
SomethingHappened -= this.HandleSomethingHappened;
//release the reference to this instance so it can be GC'd
}
}
You could use the Observer pattern. It allows objects to "subscribe" to events that they care about.

C#: events or an observer interface? Pros/cons?

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.

Categories