Event Filters - Isolation

With an architecture which isn't event driven, assigning a value to a field or a field backed property is a task which usually has no side effects. Your method can continue on assuming the assignment was successful without putting a try-catch around every assignment.

However with event driven architectures things aren't so simple. Any assignment to a value which raises events can now potentially throw an exception and disrupt your logic. In addition, if a value has multiple event handlers and one throws an exception, then all remaining event handlers won't be called at all.

This can make it very hard to write code which depends on knowing about every single value change to a property.

Event Handler Isolation

MetaProperties addresses this problem with a system which isolates each event handler and redirects any thrown exceptions to your own code to be handled. The method which sets the value, and any other event handlers, can all then execute as expected blissfully unaware that there was any problem.

To take advantage of this feature, you can attach to the static IsolatingEventFilter.UnhandledEventHandlerException event. If nothing is attached to this event then event handler isolation is disabled and any exceptions will propogate up the call stack as normal.

In addition to isolating event handlers, all other event filters are also isolated. However an event filter throwing an exception will still stop all event handlers from executing event though the method which triggered the event being raised will carry on as normal.

The event filter pipeline with isolation enabled is constructed as follows:

                                                       /-> |Isolation| -> |Event Handler|
                                                       |
 |Event Raised| -> |Isolation| -> |Event Filters| .... -> |Isolation| -> |Event Handler|
                                                       ..


The following code shows how to use the event handler isolation:

    public void IsolationExample()
    {
        Cat cat = new Cat();
        cat.NameProperty.ValueChanged += this.NameProperty_ValueChanged;

        // Attach to the IsolatingEventFilter to enable isolation.
        IsolatingEventFilter.UnhandledEventHandlerException 
            += this.IsolatingEventFilter_UnhandledEventHandlerException;

        // All the following lines are executed despite exceptions being thrown.

        cat.Name = "James";

        Console.WriteLine("Name changed to " + cat.Name);

        cat.Name = "Felix";

        Console.WriteLine("Name changed to " + cat.Name);
    }

    void IsolatingEventFilter_UnhandledEventHandlerException(object sender, Exception e)
    {
        Console.WriteLine("Exception thrown: " + e);
    }

    void NameProperty_ValueChanged(object sender, ValueChangedEventArgs<string> e)
    {
        throw new Exception("Oops");
    }

Last edited Mar 9, 2010 at 12:23 PM by jamesthurley, version 1

Comments

No comments yet.