A lot of the work I've been doing lately with .NET eventing and stuff comes down to the concept of resource-management - like how do we manage our resources' lifecycles without causing unintended negatives (like memory-leaks or performance issues). On the face of it resource-management is a problem of pluses and minuses, creating and releasing resources per their need - but the fact is, with frameworks like .NET there is so much resources creation and disposing going-on that we figuratively end up managing needles above a haystack.

The Idea: Take'em down with me

More to the point, I have this idea of managing the disposing of resources by creating a persuado supporter-dependent hierarchy of resources - sounds fancy but it is really simple. And the other part of the equation is having an API that isn't too intrusive - this is quite important to me, as I think with tiresome APIs the usefulness whether-away like a new-year's resolution.

In practical terms the disposing of resources is based around this single interface, called IDisposeRelated - which has the following make-up:

   1: public interface IDisposeRelated
   2: {
   3:     event EventHandler DisposeRelated;
   4: }

Basically, you introduce this interface on any object that wants to limit the lifespan of one or more dependent resources to no more than its own - so good candidates include user controls object or event handlers. For example we could, append the IDisposeRelated interface as such:

   1: public partial class Window1 : UserControl, IDisposeRelated   
   2: {   
   3:     public event EventHandler DisposeRelated;    // IDisposeRelated Members
   4:  
   5:     public Window1()   
   6:     {   
   7:         InitializeComponent();
   8:         this.Closing += (s, e) => 
   9:            {if (this.DisposeRelated != null) DisposeRelated(this, EventArgs.Empty);};
  10:     }
  11: }

 

 

All we are saying here is that when closing the user control raise the DisposeRelated event, indicating that you want dependent resources to be brought-down too. Do note, I don't use the word "dispose" in the strict sense as with the IDisposable interface, which relates it to releasing unmanaged resources.

Dependent Resources: Proactively com'n down

Once we have the IDisposeRelated resource defined, we indicate the dependency using (mainly) extension methods - consider two examples:

   1: this.Writer = new StreamWriter(_filePath).DisposeWith(this);
   2: // or
   3: ParentWindow.LostFocus += 
   4:     new RoutedEventHandler(ParentWindow_LostFocus).DisposeWith(this);

In line1 we are creating a new stream writer, to which we append the "DisposeWith" extension method to indicate that it should be disposed off when disposing "this". And "this" would/could be any object supporting the IDisposeRelated interface - so in other words, because the IDisposeRelated interface indicates as to when it wants to dispose related resources, we listen to that and take down any earmarked resources with it. And that's it.

The Take Down

Now, when I say "take-down" resources - the garbage collector would stare blankly first, but basically we know how to do certain stuff like with IDisposable objects we will call the Dispose method or with event handlers we can unregister it. For other stuff or when you want more control you can use another DisposeWith extension method definition that takes an action delegate (with the target passed in) to effect the "take-down" as you specify. For example:

   1: var _cache = new MemoryCache().DisposeWith(this, (c) => c.Clear());

In the case of the cache object above, the "take-down" concept in its context would mean clearing whatever is in the memory. The point being, if we can proactively add this instruction of how to redeem resources whilst creation (though you could still add these instructions later) we won't loose the proverbial needle in the haystack. Further, by earmarking resources by the "dispose with" instruction, we create this persuado supporter-dependent hierarchy.

Technically Speaking

Having specified "dispose with" for an object does not preclude you from disposing it earlier - just later if it hasn't been disposed then it will do it for you. Secondly, the "dispose with" instruction only holds a weak reference to its target, and so it doesn't itself become a memory leak source. Also, you could possibly have more than "dispose with" instructions against a resource and it will be fulfilled in a first-come first-serve basis. Further, the dispose with thing doesn't have to be based on a resource's parent's lifecycle, it could be based on a peer object or on some other domain context - which is why I said a persuado supporter-dependent relationship and not a parent-child one.

Performance-wise, I've not checked because I am still mulling over the validity of the idea. But, I don't think it would be too great of hit, because my current implementation is basically adding a weak handler against the "DisposeRelated" event. All the same, there are other ways to implement the same functionality, so we'll see about the performance.

This current implementation is very basic, possibly in the future, if it is worthy, we could add fancy features like LINQ based dependency evaluation or lazily attach it with a control's lifecycle. For now, it is something simple I am trying in my code, but like in a lot of cases ideas as these comes down to the usefulness v/s inconvenience of the feature.

Posted by Rishi on 31-Jul-09 6:33 AM, 23 Comments

Categories: Architecture, Code

Above is a simple Silverlight 3 application that demonstrates the usefulness of weak events in avoiding memory-leak issues. To demonstrate, I've made use of weak event handler wrappers I introduced in my previous post (the code can also found there). The application itself is very simple, it shows the current memory consumption, allows creation of two types of child windows and enables garbage collection on demand. The two types of child windows by design consume more than a million bytes of memory each (per instance), and both windows basically link up with the root visual's size changed event - with a call like:

   1: // Normal Child Window
   2: ((MainPage)App.Current.RootVisual).SizeChanged +=
   3:         new SizeChangedEventHandler(WeakEventChildWindow_SizeChanged);

However the Weak Event Child Window, makes the following call:

   1: // Weak Event Child Window
   2: ((MainPage)App.Current.RootVisual).SizeChanged +=
   3:       new WeakHandler<SizeChangedEventArgs, SizeChangedEventHandler>(WeakEventChildWindow_SizeChanged);

And that's the only difference between the two. Also, neither of the two handlers are unregistered on closing of the child windows (as they should). But with the weak event window, the memory is reclaimed back when the window is closed (to try open some weak event windows and then give the collect garbage hyperlink couple of clicks), whereas each and every instance of the normal window would persist in the memory until the application is closed/unloaded. The weak event child window can get by, because the event handler doesn't store a strong reference to the child window, rather it holds a weak reference which disconnects the child window's lifetime from the event sources.

Now, even though this a very contrived/simple example, it does show how a casual use of a handler can cause serious memory leaks issues (especially when they are spread out all over the place, with small amounts of leaks). On the flip side, the basic principle for correcting this is that if your event source is going to outlast the event listener's life span, then make sure the event handling is disposable/disposed with the listener closing.

Posted by Rishi on 29-Jul-09 1:00 PM, 6 Comments

Categories: Architecture

As part of the next drop of nRoute, I've been doing some work around events and listeners in .NET - the main issues have been around memory-leaks, selectively multi-casting events, performance and loose-coupling. Certainly, this is not something new and there are a number of solutions out there, but usability and performance have been the compromises which was something I wanted to avoid.

The Idea : Wrap'em

From my work on it, I take that we don't want the semantics of exposing and using events to change - so basically the the producer and consumer syntax should remains the same, however if the producers and consumers are dumb about it, I suppose we should make the messenger smarter. So here is what I'm mean:

   1: source.SomethingHappened += new WeakHandler((s, e)=>{ . });  
   2: //or 
   3: source.SomethingHappened += new WeakHandler(Handle_Something);  // delegates to a method

On the left the source exposes a "SomethingHappened" event using the EventHandler delegate, and on the right we have a custom class that handles the event - the use API is actually not far off from where we are today. We just changed the normal handlers with the "WeakHandler" class that wraps (not inherits) the actual handler and introduces the logic for weak delegation. In my solution I make use of closures and lifting .NET features to create "self-referencing" event-handler that are aware of their wrappers. It's not that hard, however the benefit is that we can make it do smart things such as respond to say a specific property change on a PropertyChanged event, consider:

   1: source.PropertyChanged += new WeakPropertyChangedHandler( 
   2:    ()=> SelectedItem,  
   3:    SelectedItem_PropertyChanged);

In this case the 'SelectedItem_PropertyChanged' method will only be called when the 'SelectedItem' property changes. And the best part is the listener or consumer is weakly referenced, so it can be available for garbage collection when it has no outstanding references (without having to remove the event handler itself). And if the listener has been disposed off, the handler will de-register itself and dispose off.

The Implementation

Like I said the event handling classes above, like WeakPropertyChangedHandler, are basically wrappers around the actual event handlers - however note, we don't need to create specific event handlers for each and every event type. We have a generic definition that can that can handle every type of event; its constructor signature is a follows:

   1: public class Handler<E, H> 
   2:        where E : EventArgs 
   3: { 
   4:     public Handler(Func<Action<Object, E>, H> createAction, Action<Object, E> action, 
   5:                 Action<H> removeAction) { .. } 
   6: }

The H type is supposed to be your handler type which unfortunately cannot be constrained. All the same, just like every event handler we need to be able to do four things, namely create the handler, attach the handler, handle the event and remove the handler. Now, if you look at the constructor we don't do the attaching part, that's up to the user but for the rest we take in delegates - so a full blown handler can be written as:

   1: Application.Current.MainWindow.SizeChanged += 
   2:     new Handler<SizeChangedEventArgs, SizeChangedEventHandler>( 
   3:     (a) => new SizeChangedEventHandler(a),    // How to create 
   4:     (s, e) => Console.WriteLine("Main Window Size Changed."),  // How to handle 
   5:     (h) => Application.Current.MainWindow.SizeChanged -= h);  // How to remove

I know that is somewhat verbose, however that's the full monty, whereas you have more specific implementations and additional constructors that can do the creation and removing part for you. The other important thing to realize is that the Handle<E,H> type can be paraded around as a named variable, consider:

   1: var _handler = new RoutedHandler((s, e) => MessageBox.Show("GotFocus"));
   2: this.GotFocus += _handler;
   3: // when done
   4: _handler.UnregisterHandler();

Here we create the handler variable, which when done can be specifically called to unregister. I specifically designed this  to call an unregister method rather than have to -= the handler.

The Variants

As you can probably tell we have many different types of handlers, which can generally be qualified into three separate categories (see below). First, we have types deriving from Handler<E,H>, which are basically like normal events wrappers that hold a direct reference to the event listener and have to be manually unregistered. The second category is based on the SingleHandler<E,H> type that only handle the first call and then recuses itself - which might seem strange, but actually they are very useful in handling things like Loaded, Initialized, Errors related events. They save memory, plus ensure you don't end up holding unnecessary references. Lastly, we have the WeakHandler<E,H>based types, which as the name suggests holds a weak reference to the listener and allow for its disposing independent of the event source. Also note, WeakHandler types also allow you to manually call the UnregisterHandler method to discontinue the event handling.

EventHandlers

As shown above, based on the three categories of handler wrappers we have specific types that handle EventHandler<E>, EventHandler, RoutedEventHandler and PropertyChangedEventHandler types of event delegates. They just allow for an easier to use API, however you could resort to the generic types if you wanted too.

Performance

Given the use syntax is very similar to the normal event handlers, the other important use tenant for me is the performance. Lets see how it fares (time in seconds):

Handler Type Action Type 1 Event 10 Events 1,000 Events 10,000 Events
System EventHandler Attach Event 0.0000059 0.0000272 0.0006216 0.0310925
  Raise Event 0.0000041 0.0000102 0.0248883 1.1368489
  Detach Event 0.0000065 0.0000254 0.0148008 0.8415036
Handler<E,H> Attach Event 0.0000852 0.0002054 0.0096227 0.0665443
  Raise Event 0.0000041 0.0000148 0.0522444 3.1837825
  Detach Event 0.0000071 0.0000272 0.0560088 2.7236017
SingleHandler<E,H> Attach Event 0.0000840 0.0001782 0.0098619 0.0592904
  Raise Event 0.0000059 0.0000201 0.0375098 2.2381572
  Detach Event 0.0000065 0.0000236 0.0530667 2.5753320
WeakHandler<E,H> Attach Event 0.00001415 0.0003268 0.0171803 0.1007618
  Raise Event 0.0000840 0.00003208 0.1420596 12.9617411
  Detach Event 0.0000065 0.0000272 0.0558754 2.7769959

Based on the table, the performance of the wrapped handlers have a disadvantage ranging from 1.5x-15x, primarily on the event raising front. Attaching is notably slower, however unless you are doing very processer intensive stuff, I think for most part these are within the range of "acceptable costs", especially for client-side apps like with Silverlight. Also, there are further optimizations to be had, as this is quite early stuff.

Listeners

Now if you like what you have seen, it gets better. Given some of the problems with eventing as it stands, the WPF team rolled out their own implementation based on the Weak Event Pattern. They essentially provided an event manager, a custom event definition wrapper, and a relative simple consumption interface - which all somewhat works like normal events. The consumption interface called IWeakEventListner has the following signature:

   1: public interface IWeakEventListener
   2: {
   3:     bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e);
   4: }

The weak event pattern is performant, but the provider side requirements of obscure per-event setup, registration and the middle men solution are all a bit clumsy. So how about if we could attach IWeakEventListner implementation to normal event handler defined events, something like this:

   1: source.SomethingHappened += new WeakListener(weakEventListnerObj);
   2: // or 
   3: source.PropertyChanged += new WeakPropertyChangedListnerHandler(
   4:     () => Items,
   5:     weakEventListnerObj);
 
Here the "SomethingHappened" is a normal event defined by the EventHandler signature, and we attach a handler that directs the handling to the a class instance implementing IWeakEventListner. The use semantics are just about the same as with normal events, and you can also detach the same by using the UnregisterMethod. You need no special registration, event-definition class, or manager, just do as you always did but with the given handlers types and it works with every event out there.
 
The Variants
 
And just like the event wrappers above, we have three categories of listeners shown below:

Listeners
 
The use semantics are basically similar to what I showed earlier, the only difference being we need to pass in an instance of IWeakEventListener rather than a delegate to handle the event. Further, because Silverlight doesn't have an build-in IWeakEventListener interface, I've provided one to compile with Silverlight whereas in the full-blown .NET version you would/can use the WPF defined interface. Also since we don't have a "managerType" as specified by the RecieveWeakEvent method, we pass in the type of EventHandler - so for a property changed event you will get the PropertyChangedHandler type passed in as the managerType. Further, by returning false you can unregister from the event and the wrapper will dispose itself.
 
Performance
 
Listeners with event handlers numbers (in seconds):

Handler Type Action Type 1 Event 10 Events 1000 Events 10,000 Events
System EventHandler Attach Event 0.0000059 0.0000272 0.0006216 0.0310925
  Raise Event 0.0000041 0.0000082 0.0248883 1.1368489
  Detach Event 0.0000065 0.0000254 0.0148008 0.8415036
ListenerHandler<E,H> Attach Event 0.0000976 0.0001598 0.0101366 0.0606196
  Raise Event 0.0000059 0.0000142 0.0493853 3.6426401
  Detach Event 0.0000071 0.0000219 0.0460088 2.6254094
SingleListenerHandler<E,H> Attach Event 0.0000828 0.0001557 0.0102970 0.0610187
  Raise Event 0.0000102 0.0000159 0.0337023 2.4158356
  Detach Event 0.0000082 0.0000165 0.0435121 2.5886397
WeakListenerHandler<E,H> Attach Event 0.0001053 0.00001409 0.0115611 0.0699055
  Raise Event 0.0000106 0.0000224 0.099667 7.3137979
  Detach Event 0.0000082 0.0000266 0.0446755 2.7211488

Based on the figures above the build in handlers still have a distinct advantage, however it is less pronounced. And again from my perspective, the costs of using listeners with events are nominal. And, with respect to handlers performance listed earlier, listeners fare much better considering the conversions between delegate to interface based handling.

There is More

As I mentioned this is early work, so I have a couple of things in mind for improvements:
  • Possibly, implement IDisposable on all the handlers, not for reclaiming unmanaged resources use but more for user's remember-to-dispose considerations. I'm still thinking about this
  • Introducing -= operator, I personally prefer the use of the UnregisterHandler method
  • Introducing a common base class, with overridable methods
  • Because I'ved used a lot of lambda statements, I want to see if there is a way to increase performance. Also if I understand correctly in .NET 4 lambda statements can be compiled (as opposed to only expressions right now), which should help with performance
  • I also want to further squeeze performance out of the Weak handlers, I've used a number of techniques to ensure through-and-through performance, but I still think there might be better ways. I am looking at late-bound expression trees to see if they can help, if you know of any better way please let me know
  • I'm also looking for alternative and strongly-typed ways to create and remove handlers. What I have currently, it's quite performant but there might be a better way
  • Also I think with .NET 4.0's dynamic types we might be able to hopefully get some improvement in performance, especially since we will be able to rigorously match event defined signature with delegates
  • For Silverlight, there is an access limitation to only being able to call public methods and not private ones - I want to if there is an alternative to that (note this only effects the Weak Handlers types). If you know of any alternatives, do let me know

The code is attached below, it references the "WindowsBase" dll for the IWeakEventListener interface - but if you want to use this in non-WPF environments then just expose the interface and remove the RoutedHandlers related classes. Similarly, for use in Silverlight, just link/add the code to a Silverlight project and it should compile as is. 

Download Code (updated for Silverlight use)

Update: I re-did all the performance tests because they were highly skewed in favour of listeners - because earlier the handlers did not do any work. The new figures, better represent real-usage and reflect the expected costs of wrapping event handlers.

I've moved my blog from orkpad.com to orktane.com, that's because the domain orkpad.com expired last sunday and some bot  took it up before I could notice. My domain provider had only send me a single bill like two months ago, with no follow-ups - I thought it had been auto-renewed, but somehow that "option" was off. Well, I'm working to get the domain back, but from now-on this will be the permanent home for my blog and related stuff.

The lesson, keep one domain provider and ensure you have the auto-renew thing on.

Posted by Rishi on 29-Jul-09 3:56 AM, 6 Comments