I'm reading the MS docs on how to implement the weak event pattern. I've tried the first two (since I'm looking for the simplest way) but I can't find a way to raise the event.
The existing weak event managers like the PropertyChangedEventManager, and the generic WeakEventManager only have methods to add and remove handlers but nothing to raise the event. Also, I can't inherit those it says [the base class] does not contain a constructor that takes 0 arguments (the constructors are private).
So I'm finding the docs confusing - how are these constituted the ways to implement the weak event pattern if there's no way to raise the event?
If the suggested way in the docs doesn't work I'm looking for the simplest way to raise and handle weak events.
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.
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);
}
}
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.
A few years ago, I read a book that described how you could override the default event 'dispatcher' implementation in .NET with your own processor.
class foo {
public event EventHandler myEvent;
...
}
...
myFoo.myEvent += myBar1.EventHandler;
myFoo.myEvent += myBar2.EventHandler;
Whenever the event fires, both myBar1 and myBar2 handlers will be called.
As I recall, the default implementation of this loop uses a linked list and simply iterates over the list and calls the EventHandler delegates in order.
My question is two fold:
Does someone know which book I was reading?
Why would you want to override the default implementation (which might be answered in the book)?
Edit: The book I was referring to was indeed Jeffrey Richter's CLR via C#
It could have been one of many books or web articles.
There are various reasons why you might want to change how events are subscribed/unsubscribed:
If you have many events, many of which may well not be subscribed to, you may want to use EventHandlerList to lower your memory usage
You may wish to log subscription/unsubscription
You may wish to use a weak reference to avoid the subscriber's lifetime from being tied to yours
You may wish to change the locking associated with subscription/unsubscription
I'm sure there are more - those are off the top of my head :)
EDIT: Also note that there's a difference between having a custom way of handling subscription/unsubscription and having a custom way of raising the event (which may call GetInvocationList and guarantee that all handlers are called, regardless of exceptions, for example).
I seem to remember something similar in Jeffrey Richter's CLR via C#. Edit: I definitely do remember that he goes into detail about it.
There are a few different reasons for taking control of event registration. One of them is to reduce code bloat when you've got TONS of events. I think Jeffrey went into this in detail within the book...
No
You might, for example, need to break the call chain based on the result of one of the handlers. Say your CustomEventArgs object has a property 'Blocked', which when set to true suppresses all further event handler invocations.