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.
Related
I'm learning how to incorporate IObservable into my code. Below are two different approaches for a simple class that prints out the most recent word from an IObservable<string>. Which is the cleaner approach? I don't like WordPrinterWithCache because it introduces additional state (the _lastWord) variable and the interesting code is now scattered throughout the class. I prefer WordPrinterWithExtraSubject because the interesting code is localized to the constructor. But mostly it seems more consistently functional and "reactive"; I am reacting to the combination of two "events": (1) a new word being emitted, and (2) the invocation of the PrintMostRecent method.
However I have read that using Subjects is not desirable when it is not strictly necessary and I am introducing an unnecessary Subject<Unit>. Essentially what I'm doing here is generating an observable from a method call so I can use the observable combinator functions in more places. I like the idea of building up my code using the observable combinators and subscriptions rather than using "old-style" method invocation trees. I don't know if this is a good idea.
public class WordPrinterWithCache
{
string _lastWord = string.Empty;
public WordPrinterWithCache(IObservable<string> words)
{
words.Subscribe(w => _lastWord = w);
}
public void PrintMostRecent() => Console.WriteLine(_lastWord);
}
public class WordPrinterWithExtraSubject
{
Subject<Unit> _printRequest = new Subject<Unit>();
public WordPrinterWithExtraSubject(IObservable<string> words)
{
_printRequest
.WithLatestFrom(words.StartWith(string.Empty), (_, w) => w)
.Subscribe(w => Console.WriteLine(w));
}
public void PrintMostRecent() => _printRequest.OnNext(Unit.Default);
}
The actual scenario in my code is that I have an ICommand. When the user invokes the command (maybe by clicking a button), I want to take action on the most recent value of a specific observable. For example, maybe the ICommand represents Delete and I want to delete the selected item in a list that is represented by an IObservable<Guid>. It gets ugly to keep a bunch of "last emitted value" cache variables for each observable.
The approach I'm leaning toward is an ICommand implementation kind of like what you see below. This allows me to write code like deleteCommand.WithLatestFrom(selectedItems,(d,s)=>s).Subscribe(selected=>delete(selected));
public class ObservableCommand : ICommand, IObservable<object>
{
bool _mostRecentCanExecute = true;
Subject<object> _executeRequested = new Subject<object>();
public ObservableCommand(IObservable<bool> canExecute)
{
canExecute.Subscribe(c => _mostRecentCanExecute = c);
}
public event EventHandler CanExecuteChanged; // not implemented yet
public bool CanExecute(object parameter) => _mostRecentCanExecute;
public void Execute(object parameter) => _executeRequested.OnNext(parameter);
public IDisposable Subscribe(IObserver<object> observer) => _executeRequested.Subscribe(observer);
}
So as a general rule (guideline), I strongly suggest not having an IObservable<T> as a parameter to a method. The obvious caveat being if that method is a new Rx Operator e.g. Select, MySpecialBuffer, Debounce etc.
The theory here is that IObservable<T> is a callback mechanism. It allows something to callback to another thing that it otherwise knows nothing about. However in this case, you have something that knows about both the IObservable<T> (parameter) and the other thing (WordPrinterWithCache).
So why is there this extra layer of indirection? What ever it was that was pushing values to the IObservable<T> could just instead call a method of the WordPrinterWithCache instance.
In this case, just call a method on the other thing
public class WordPrinterWithCache
{
private string _lastWord = string.Empty;
public void SetLastWord(string word)
{
_lastWord = word;
}
public void PrintMostRecent() => Console.WriteLine(_lastWord);
}
Now this class starts to look rather pointless, but that might be ok. Simple is good.
Use Rx to help you with layering.
Upstream layers depend on down stream layers. They will directly call methods (issue commands) on the downstream layers.
Downstream layers wont have access to upstream layers. So to expose data to them they can either return values from methods, or can expose callbacks. The GoF Observer patter, .NET Events and Rx are ways to provide callbacks to upstream layers.
While I'm not sure I'd use the term "turning a method call into an observable event", I have been a fan of using fully declarative, functional and Rx driven code for a while now.
Your description of an ICommand implementation matches very closely with one I wrote a couple of years ago and have used many times and very successfully since. Furthermore, this has become the basis for a pattern I refer to as "Reactive Behaviors" which provides numerous benefits. From my blog:
Promotes behavior driven development and unit testing.
Promotes functional and thread safe programming practises.
Reduces the risk of (and if done well, can eliminate) side effects as specific behaviors are isolated in a single well named method.
Stops 'code rot' as all behavior is encapsulated within specifically named methods. Want new behaviour? Add a new method. Don't want a specific behavior anymore? Just removed it. Want a specific behavior to change? Change the one method and know that you haven't broken anything else.
Provides concise mechanisms for aggregating multiple inputs and promotes asynchronous processes to first-class status.
Reduces the need for utility classes as data can be passed through the pipeline as strongly typed anonymous classes.
Prevents memory leaks as all behaviors return a disposable that when disposed removes all subscriptions and disposed all managed resources.
You can read the full article on my blog.
I am currently getting to grips with the Reactive Extensions framework for .NET and I am working my way through the various introduction resources I've found (mainly http://www.introtorx.com)
Our application involves a number of hardware interfaces that detect network frames, these will be my IObservables, I then have a variety of components that will consume those frames or perform some manner of transform on the data and produce a new type of frame. There will also be other components that need to display every n'th frame for example.
I am convinced that Rx is going to be useful for our application, however I am struggling with the implementation details for the IObserver interface.
Most (if not all) of the resources I have been reading have said that I should not implement the IObservable interface myself but use one of the provided functions or classes.
From my research it appears that creating a Subject<IBaseFrame> would provide me what I need, I would have my single thread that reads data from the hardware interface and then calls the OnNext function of my Subject<IBaseFrame> instance. The different IObserver components would then receive their notifications from that Subject.
My confusion is coming from the advice give in the appendix of this tutorial where it says:
Avoid the use of the subject types. Rx is effectively a functional programming paradigm. Using subjects means we are now managing state, which is potentially mutating. Dealing with both mutating state and asynchronous programming at the same time is very hard to get right. Furthermore, many of the operators (extension methods) have been carefully written to ensure that correct and consistent lifetime of subscriptions and sequences is maintained; when you introduce subjects, you can break this. Future releases may also see significant performance degradation if you explicitly use subjects.
My application is quite performance critical, I am obviously going to test the performance of using the Rx patterns before it goes in to production code; however I am worried that I am doing something that is against the spirit of the Rx framework by using the Subject class and that a future version of the framework is going to hurt performance.
Is there a better way of doing what I want? The hardware polling thread is going to be running continuously whether there are any observers or not (the HW buffer will back up otherwise), so this is a very hot sequence. I need to then pass the received frames out to multiple observers.
Any advice would be greatly appreciated.
Ok,
If we ignore my dogmatic ways and ignore "subjects are good/bad" all together. Let us look at the problem space.
I bet you either have 1 of 2 styles of system you need to ingrate to.
The system raises an event or a call back when a message arrives
You need to poll the system to see if there are any message to process
For option 1, easy, we just wrap it with the appropriate FromEvent method and we are done. To the Pub!
For option 2, we now need to consider how we poll this and how to do this effciently. Also when we get the value, how do we publish it?
I would imagine that you would want a dedicated thread for polling. You wouldn't want some other coder hammering the ThreadPool/TaskPool and leaving you in a ThreadPool starvation situation. Alternatively you don't want the hassle of context switching (I guess). So assume we have our own thread, we will probably have some sort of While/Sleep loop that we sit in to poll. When the check finds some messages we publish them. Well all of this sounds perfect for Observable.Create. Now we probably cant use a While loop as that wont allow us to ever return a Disposable to allow cancellation. Luckily you have read the whole book so are savvy with Recursive scheduling!
I imagine something like this could work. #NotTested
public class MessageListener
{
private readonly IObservable<IMessage> _messages;
private readonly IScheduler _scheduler;
public MessageListener()
{
_scheduler = new EventLoopScheduler();
var messages = ListenToMessages()
.SubscribeOn(_scheduler)
.Publish();
_messages = messages;
messages.Connect();
}
public IObservable<IMessage> Messages
{
get {return _messages;}
}
private IObservable<IMessage> ListenToMessages()
{
return Observable.Create<IMessage>(o=>
{
return _scheduler.Schedule(recurse=>
{
try
{
var messages = GetMessages();
foreach (var msg in messages)
{
o.OnNext(msg);
}
recurse();
}
catch (Exception ex)
{
o.OnError(ex);
}
});
});
}
private IEnumerable<IMessage> GetMessages()
{
//Do some work here that gets messages from a queue,
// file system, database or other system that cant push
// new data at us.
//
//This may return an empty result when no new data is found.
}
}
The reason I really don't like Subjects, is that is usually a case of the developer not really having a clear design on the problem. Hack in a subject, poke it here there and everywhere, and then let the poor support dev guess at WTF was going on. When you use the Create/Generate etc methods you are localizing the effects on the sequence. You can see it all in one method and you know no-one else is throwing in a nasty side effect. If I see a subject fields I now have to go looking for all the places in a class it is being used. If some MFer exposes one publicly, then all bets are off, who knows how this sequence is being used!
Async/Concurrency/Rx is hard. You don't need to make it harder by allowing side effects and causality programming to spin your head even more.
In general you should avoid using Subject, however for the thing you are doing here I think they work quite well. I asked a similar question when I came across the "avoid subjects" message in Rx tutorials.
To quote Dave Sexton (of Rxx)
"Subjects are the stateful components of Rx. They are useful for when
you need to create an event-like observable as a field or a local
variable."
I tend to use them as the entry point into Rx. So if I have some code that needs to say 'something happened' (like you have), I would use a Subject and call OnNext. Then expose that as an IObservable for others to subscribe to (you can use AsObservable() on your subject to make sure nobody can cast to a Subject and mess things up).
You could also achieve this with a .NET event and use FromEventPattern, but if I'm only going to turn the event into an IObservable anyway, I don't see the benefit of having an event instead of a Subject (which might mean I'm missing something here)
However, what you should avoid quite strongly is subscribing to an IObservable with a Subject, i.e. don't pass a Subject into the IObservable.Subscribe method.
Often when you're managing a Subject, you're actually just reimplementing features already in Rx, and probably in not as robust, simple and extensible a way.
When you're trying to adapt some asynchronous data flow into Rx (or create an asynchronous data flow from one that's not currently asynchronous), the most common cases are usually:
The source of data is an event: As Lee says, this is the simplest case: use FromEvent and head to the pub.
The source of data is from a synchronous operation and you want polled updates, (eg a webservice or database call): In this case you could use Lee's suggested approach, or for simple cases, you could use something like Observable.Interval.Select(_ => <db fetch>). You may want to use DistinctUntilChanged() to prevent publishing updates when nothing has changed in the source data.
The source of data is some kind of asynchronous api that calls your callback: In this case, use Observable.Create to hook up your callback to call OnNext/OnError/OnComplete on the observer.
The source of data is a call that blocks until new data is available (eg some synchronous socket read operations): In this case, you can use Observable.Create to wrap the imperative code that reads from the socket and publishes to the Observer.OnNext when data is read. This may be similar to what you're doing with the Subject.
Using Observable.Create vs creating a class that manages a Subject is fairly equivalent to using the yield keyword vs creating a whole class that implements IEnumerator. Of course, you can write an IEnumerator to be as clean and as good a citizen as the yield code, but which one is better encapsulated and feels a neater design? The same is true for Observable.Create vs managing Subjects.
Observable.Create gives you a clean pattern for lazy setup and clean teardown. How do you achieve this with a class wrapping a Subject? You need some kind of Start method... how do you know when to call it? Or do you just always start it, even when no one is listening? And when you're done, how do you get it to stop reading from the socket/polling the database, etc? You have to have some kind of Stop method, and you have to still have access not just to the IObservable you're subscribed to, but the class that created the Subject in the first place.
With Observable.Create, it's all wrapped up in one place. The body of Observable.Create is not run until someone subscribes, so if no one subscribes, you never use your resource. And Observable.Create returns a Disposable that can cleanly shutdown your resource/callbacks, etc - this is called when the Observer unsubscribes. The lifetimes of the resources you're using to generate the Observable are neatly tied to the lifetime of the Observable itself.
The quoted block text pretty much explains why you shouldn't be using Subject<T>, but to put it simpler, you are combining the functions of observer and observable, while injecting some sort of state in between (whether you're encapsulating or extending).
This is where you run into trouble; these responsibilities should be separate and distinct from each other.
That said, in your specific case, I'd recommend that you break your concerns into smaller parts.
First, you have your thread that is hot, and always monitoring the hardware for signals to raise notifications for. How would you do this normally? Events. So let's start with that.
Let's define the EventArgs that your event will fire.
// The event args that has the information.
public class BaseFrameEventArgs : EventArgs
{
public BaseFrameEventArgs(IBaseFrame baseFrame)
{
// Validate parameters.
if (baseFrame == null) throw new ArgumentNullException("IBaseFrame");
// Set values.
BaseFrame = baseFrame;
}
// Poor man's immutability.
public IBaseFrame BaseFrame { get; private set; }
}
Now, the class that will fire the event. Note, this could be a static class (since you always have a thread running monitoring the hardware buffer), or something you call on-demand which subscribes to that. You'll have to modify this as appropriate.
public class BaseFrameMonitor
{
// You want to make this access thread safe
public event EventHandler<BaseFrameEventArgs> HardwareEvent;
public BaseFrameMonitor()
{
// Create/subscribe to your thread that
// drains hardware signals.
}
}
So now you have a class that exposes an event. Observables work well with events. So much so that there's first-class support for converting streams of events (think of an event stream as multiple firings of an event) into IObservable<T> implementations if you follow the standard event pattern, through the static FromEventPattern method on the Observable class.
With the source of your events, and the FromEventPattern method, we can create an IObservable<EventPattern<BaseFrameEventArgs>> easily (the EventPattern<TEventArgs> class embodies what you'd see in a .NET event, notably, an instance derived from EventArgs and an object representing the sender), like so:
// The event source.
// Or you might not need this if your class is static and exposes
// the event as a static event.
var source = new BaseFrameMonitor();
// Create the observable. It's going to be hot
// as the events are hot.
IObservable<EventPattern<BaseFrameEventArgs>> observable = Observable.
FromEventPattern<BaseFrameEventArgs>(
h => source.HardwareEvent += h,
h => source.HardwareEvent -= h);
Of course, you want an IObservable<IBaseFrame>, but that's easy, using the Select extension method on the Observable class to create a projection (just like you would in LINQ, and we can wrap all of this up in an easy-to-use method):
public IObservable<IBaseFrame> CreateHardwareObservable()
{
// The event source.
// Or you might not need this if your class is static and exposes
// the event as a static event.
var source = new BaseFrameMonitor();
// Create the observable. It's going to be hot
// as the events are hot.
IObservable<EventPattern<BaseFrameEventArgs>> observable = Observable.
FromEventPattern<BaseFrameEventArgs>(
h => source.HardwareEvent += h,
h => source.HardwareEvent -= h);
// Return the observable, but projected.
return observable.Select(i => i.EventArgs.BaseFrame);
}
It is bad to generalize that Subjects are not good to use for a public interface.
While it is certainly true, that this is not the way a reactive programming approach should look like, it is definitively a good improvement/refactoring option for your classic code.
If you have a normal property with an public set accessor and you want to notify about changes, there speaks nothing against replacing it with a BehaviorSubject.
INPC or additional other events are just not that clean and it personally wears me off.
For this purpose you can and should use BehaviorSubjects as public properties instead of normal properties and ditch INPC or other events.
Additionally the Subject-interface makes the users of your interface more aware about the functionality of your properties and are more likely to subscribe instead of just getting the value.
It is the best to use if you want others to listen/subscribe to changes of a property.
I have a class that handles events from a WinForms control. Based on what the user is doing, I am deferencing one instance of the class and creating a new one to handle the same event. I need to unsubscribe the old instance from the event first - easy enough. I'd like to do this in a non-proprietary manner if possible, and it seems like this is a job for IDisposable. However, most documentation recommends IDisposable only when using unmanaged resources, which does not apply here.
If I implement IDisposable and unsubscribe from the event in Dispose(), am I perverting its intention? Should I instead provide an Unsubscribe() function and call that?
Edit: Here's some dummy code that kind of shows what I'm doing (using IDisposable). My actual implementation is related to some proprietary data binding (long story).
class EventListener : IDisposable
{
private TextBox m_textBox;
public EventListener(TextBox textBox)
{
m_textBox = textBox;
textBox.TextChanged += new EventHandler(textBox_TextChanged);
}
void textBox_TextChanged(object sender, EventArgs e)
{
// do something
}
public void Dispose()
{
m_textBox.TextChanged -= new EventHandler(textBox_TextChanged);
}
}
class MyClass
{
EventListener m_eventListener = null;
TextBox m_textBox = new TextBox();
void SetEventListener()
{
if (m_eventListener != null) m_eventListener.Dispose();
m_eventListener = new EventListener(m_textBox);
}
}
In the actual code, the "EventListener" class is more involved, and each instance is uniquely significant. I use these in a collection, and create/destroy them as the user clicks around.
Conclusion
I'm accepting gbjbaanb's answer, at least for now. I feel that the benefit of using a familiar interface outweighs any possible downside of using it where no unmanaged code is involved (how would a user of this object even know that?).
If anyone disagrees - please post/comment/edit. If a better argument can be made against IDisposable, then I'll change the accepted answer.
Yes, go for it. Although some people think IDisposable is implemented only for unmanaged resources, this is not the case - unmanaged resources just happens to be the biggest win, and most obvious reason to implement it. I think its acquired this idea because people couldn't think of any other reason to use it. Its not like a finaliser which is a performance problem and not easy for the GC to handle well.
Put any tidy-up code in your dispose method. It'll be clearer, cleaner and significantly more likely to prevent memory leaks and a damn sight easier to use correctly than trying to remember to un-do your references.
The intention of IDisposable is to make your code work better without you having to do lots of manual work. Use its power in your favour and get over some artificial "design intention" nonsense.
I remember it was difficult enough to persuade Microsoft of the usefulness of deterministic finalisation back when .NET first came out - we won the battle and persuaded them to add it (even if it was only a design pattern at the time), use it!
My personal vote would be to have an Unsubscribe method in order to remove the class from events. IDisposable is a pattern intended for deterministic release of unmanaged resources. In this case you not managing any unmanaged resources and therefore should not be implementing IDisposable.
IDisposable can be used to manage event subscriptions but probably shouldn't. For an example I point you to WPF. This is a library rife with events and event handlers. Yet virtually no class in WPF implements IDisposable. I would take that as an indication that events should be managed another way.
One thing that bothers me about using IDisposable pattern for unsubscribe from events is Finalization issue.
Dispose() function in IDisposable is supposed to be called by the developer, HOWEVER, if it isn't called by the developer, it is a understood that the GC will call this function (by the standard IDisposable pattern, at least). In your case, however, if you don't call Dispose no one else will - The event remains and the strong reference holds GC from calling the finalizer.
The mere fact that Dispose() won't be called automatically by GC seems to me enough to not to use IDisposable in this case. Perhaps it calls for a new application specific interface that says that this type of object must have a Cleanup function called to be disposed by GC.
I think disposable is for anything that GC can't take care of automatically, and event references count in my book. Here is a helper class I came up with.
public class DisposableEvent<T> : IDisposable
{
EventHandler<EventArgs<T>> Target { get; set; }
public T Args { get; set; }
bool fired = false;
public DisposableEvent(EventHandler<EventArgs<T>> target)
{
Target = target;
Target += new EventHandler<EventArgs<T>>(subscriber);
}
public bool Wait(int howLongSeconds)
{
DateTime start = DateTime.Now;
while (!fired && (DateTime.Now - start).TotalSeconds < howLongSeconds)
{
Thread.Sleep(100);
}
return fired;
}
void subscriber(object sender, EventArgs<T> e)
{
Args = e.Value;
fired = true;
}
public void Dispose()
{
Target -= subscriber;
Target = null;
}
}
which lets you write this code :
Class1 class1 = new Class1();
using (var x = new DisposableEvent<object>(class1.Test))
{
if (x.Wait(30))
{
var result = x.Args;
}
}
One side effect, you must not use the event keyword on your events, since that prevents passing them as a parameter to the helper constructor, however, that seems to not have any ill effects.
Another option would be to use weak delegates or something like WPFs weak events, instead of having to unsubscribe explicitly.
P.S. [OT] I consider the decision to only provide strong delegates the single most expensive design mistake of the .NET platform.
From all that i read about disposables i would argue that they were really mainly invented for solving one problem: freeing unmanaged system resources in a timely manner. But still all examples that i found are not only focussed on the topic of unmanaged resources, but also have another property in common:
Dispose is called just to speed up a process that otherwise would have occured later on automatically (GC -> finalizer -> dispose)
Calling a dispose method that unsubscribes from an event however would never occur automatically, even if you would add a finalizer that would call your dispose. (at least not as long as the event owning object exists - and if it would be called you wouldn't benefit from the unsubscription, since the event owning object would also be gone anyway)
So the main difference is that events somehow build an object graph that can't be collected, since the event handling object suddenly becomes referenced of the service that you just wanted to reference/use. You suddenly are forced to call Dispose - no automatic disposal is possible. Dispose would thereby get a subtle other meaning than that found in all examples where a Dispose call - in dirty theory ;) - isn't necessary, since it would get called automaically (at some time)...
Anyway.
Since the disposable pattern is something that already is pretty complicated (deals with finalizers that are hard to get right and many guidelines / contracts) and more importantly in most points has nothing to do with the event back referencing topic, i would say it would be easier to get that separeted in our heads by just not using that metaphor for something that could be called "unroot from object graph" / "stop" / "turn off".
What we want to achieve is to disable / stop some behaviour (by unsubscribing from an event).
It would be nice to have a standard interface like IStoppable with a Stop() method, that by contract is just focussed on
getting the object (+ all its own stoppables) disconnected from events of any objects that it didn't create by its own
so that it won't get called in implicit event style manner any longer (therefore can be perceived as stopped)
can be collected as soon any traditional references onto that object are gone
Let's call the only interface method that does the unsubscription "Stop()". You would know that the stopped object is in a acceptable state but only is stopped. Maybe a simple property "Stopped" would also be a nice to have.
It even would make sense to have an interface "IRestartable" that inherits from IStoppable and additionally has a method "Restart()" if you just want to pause a certain behaviour that certainly will be needed again in the future, or to store a deleted model object in a history for later undo recovery.
After all writing i have to confess to have just seen an example of IDisposable somewhere over here: http://msdn.microsoft.com/en-us/library/dd783449%28v=VS.100%29.aspx
But anyway until i get every detail and the original motivation of IObservable i would say it is not the best use case example
since again it is a pretty complicated system around it and we only have a small problem over here
and it might be that one of the motivations of that that whole new system is to get rid of events in the first place, which would result in a sort of stack overflow concerning th e original question
But it seems they are on some right track. Anyway: they should have used my interface "IStoppable" ;) since i strongly believe there is a difference in
Dispose: "you should call that method or something might leak if the GC happens to late" ....
and
Stop: "you have to call this method to stop a certain behaviour"
IDisposable is firmly about resources, and the source of enough problems to not muddy the waters further I think.
I'm voting for an Unsubscribe method on your own Interface too.
One option may be not to unsubscribe at all - just to change what the subscription means. If the event handler could be made smart enough to know what it's meant to do based on the context, you don't need to unsubscribe in the first place.
That may or may not be a good idea in your particular case - I don't think we've really got enough information - but it's worth considering.
No, you're not preventing the intention of IDisposable. IDisposable is intended as an all-purpose way to ensure that when you're done using an object, you can proactively clean up everything tied to that object. It doesn't have to be only unmanaged resources, it can include managed resources too. And an event subscription is just another managed resource!
A similar scenario that frequently arises in practice is that you will implement IDisposable on your type, purely in order to ensure you can call Dispose() on another managed object. This is not a perversion either, it is just tidy resource management!
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.
When would you favour using a callback (i.e, passing in a Func or Action), as opposed to exposing and using an event?
UPDATE
What motivated this question was the following problem:
I have a ThingsHandler class, which
can be associated with a ThingEditor.
The ThingsHandler handles a list of
Things, knows their order, which one is 'current', when new
ones are added or deleted etc.
The ThingEditors can just modify a single
thing.
The ThingsHandler needs to alert
the ThingEditor when the user selects
a new Thing to edit, and the
ThingEditor needs to alert the
ThingsHandler when the user says
'done'.
What bothers me is having these two classes holding references to each other - though I guess that's inevitable - or binding to events in both directions. I wondered if using a callback in one direction was 'cleaner'.
I suspect there is a design pattern for this.
Though the other answers thus far seem reasonable, I would take a more philosophical tack.
A class is a mechanism that models a particular kind of thing in a particular domain. It is very easy when writing the internal details of a class to conflate the implementation details of the mechanism with the semantics being modeled. A brief example of what I mean:
class Giraffe : Mammal, IDisposable
{
public override void Eat(Food f) { ... }
public void Dispose() { ... }
}
Notice how we've conflated the real-world thing being modeled (a giraffe is a kind of mammal, a giraffe eats food) with the details of the implementation (an instance of Giraffe is an object which can be disposed of with the "using" statement). I guarantee that if you go to the zoo, you will never see a giraffe being disposed of with the using statement. We've mixed up the levels here, which is unfortunate.
I try to use events (and properties) as part of the semantic model and use callback methods (and fields) as part of the mechanism. I would make GaveBirth an event of Giraffe, since that is part of the model of real-world giraffe behaviour we're attempting to capture. If I had some mechanism, like, say I wanted to implement an inorder-walk tree traversal algorithm that walked the family tree of giraffes and called a method back on every one, then I'd say that this was clearly a mechanism and not part of the model, and make it a callback rather than try to shoehorn that into the event model.
I use callbacks in a few cases where I know it will only ever fire once, and the callback is specific to a single method call (rather than to an object instance) - for example, as the return part of an async method.
This is particularly true of static utility methods (since you don't have an instance, and static events are deadly when used carelessly, and to be avoided), but of course the other option is to create a class instance with an event instead.
Generally, I use a callback if it is required, whereas an event is used when it should be optional.
Don't expose an event if you're expecting there to always be something listening.
Consider the following:
public class MyClass_Event
{
public event EventHandler MakeMeDoWork;
public void DoWork()
{
if (MakeMeDoWork == null)
throw new Exception("Set the event MakeMeDoWork before calling this method.");
MakeMeDoWork(this, EventArgs.Empty);
}
}
versus:
public class MyClass_Callback
{
public void DoWork(EventHandler callback)
{
if (callback == null)
throw new ArgumentException("Set the callback.", "callback"); // better design
callback(this, EventArgs.Empty);
}
}
The code is almost the same as the callback can be passed as null, but at least the exception thrown can be more relevant.
Callbacks are good when one object wishes to receive a single notification (e.g. an Async data read runs and then calls you with the result).
Events are good for recurring notifications that can be received by an arbitrary number of listeners.
One example is when the callback should return something. E.g. (stupid example):
public int Sum(Func<int> callbackA, Func<int> callbackB) {
return callbackA() + callbackB();
}
public void UseSum() {
return sum(() => 10, () => 20);
}
In terms of OO design and class coupling there isn't great deal of difference between a callback interface and an event.
However, I prefer events where they are things the class needs to "shout about" to whoever is interested in listening (usually multiple things) and callbacks where a specific class has requested an async operation.
Whatever you use, use them consistently across the codebase!
I would use Func or Action when I am going to call the function once or use a Lambda expression.
Events can be registered more than once which sometimes is ideal. With a callback, one has to implement a registration system for the callbacks if you want multiple.
Well, I think they are same things. There're many different tech terms to name the same concepts or things in the different languages.
So, what do you mean "Callback" or "event handler"?
According to MSDN: Callback function is code within a managed application that helps an unmanaged DLL function complete a task.
And, MADN also gives us a introduction of the difference between them.click here
Callbacks are extensibility points that allow a framework to call back into user code through a delegate. These delegates are usually passed to the framework through a parameter of a method.
Events are a special case of callbacks that supports convenient and consistent syntax for supplying the delegate (an event handler). In addition, Visual Studio’s statement completion and designers provide help in using event-based APIs
Also, in some books, such as this book, the author seemed say the same thing with MSDN.
Therefore, in my opinion, you can't say use callbacks instead of events in the C#.