Unit Testing Multi-Threaded Asynchronous Events

I recently developed a stress/load testing tool. One of the classes implemented the Event-based Asynchronous Pattern. A good unit test for this class would be that the event is raised when expected (or at all). I found some posts on how to test events using NUnit. However, I did not see anything directly addressing the multi-threaded asynch event pattern. The following unit test uses an anonymous method and the ManualResetEvent to verify that the RunCompleted event fires after the call to RunAsync.

[Test()]
public void AfterRunAsync()
{
    ManualResetEvent manualEvent = new ManualResetEvent(false);

    TestTestCase tc = new TestTestCase(1, "", 0, 0);
    bool eventFired = false;
    tc.RunCompleted +=
        delegate(object sender, AsyncCompletedEventArgs e) {
            Assert.IsInstanceOfType(typeof (TestTestCase), sender, "sender is TestCase");
            bool passed = tc.Passed;
            string output = tc.Output;
            eventFired = true;
            manualEvent.Set();
        };
    tc.RunAsync();
    manualEvent.WaitOne(500, false);
    Assert.IsTrue(eventFired, "RunCompleted fired");
}

Databinding Magic with Dynamic PropertyDescriptors and Anonymous Methods

At the end of my post, Implementing ITypedList for Virtual Properties, I mentioned the possibility of having one, very-versatile, subclass of PropertyDescriptor that could handle all of your virtual property databinding needs. I was implementing ITypedList again and I didn’t want to write yet another set of type-specific PropertyDescriptor subclasses so I knocked this out. Everything went really well until I was creating anonymous methods inside of a foreach loop. Be sure to see the caveat below on this before you try to use this class. Without further ado, here is DynamicPropertyDescriptor (props to manoli.net for providing the code formatter I used in this post):

public delegate object DynamicGetValue(object component);
public delegate void DynamicSetValue(object component, object newValue);

public class DynamicPropertyDescriptor : PropertyDescriptor {
    protected Type _componentType;
    protected Type _propertyType;
    protected DynamicGetValue _getDelegate;
    protected DynamicSetValue _setDelegate;

    public DynamicPropertyDescriptor(Type componentType, string name, Type propertyType, 
        DynamicGetValue getDelegate, DynamicSetValue setDelegate)
        :
        base(name, null) {
        _componentType = componentType;
        _propertyType = propertyType;
        _getDelegate = getDelegate;
        _setDelegate = setDelegate;
    }

    public override bool CanResetValue(object component) {
        return false;
    }

    public override Type ComponentType {
        get { return _componentType; }
    }

    public override object GetValue(object component) {
        return _getDelegate(component);        
    }

    public override bool IsReadOnly {
        get { return _setDelegate == null; }
    }

    public override Type PropertyType {
        get { return _propertyType; }
    }

    public override void ResetValue(object component) {
    }

    public override void SetValue(object component, object value) {
        _setDelegate(component, value);
    }

    public override bool ShouldSerializeValue(object component) {
        return true;
    }
}

I will reuse the Person and related classes from the prior post. This time, I will demonstrate an actual crosstab with editable values by adding an “hours worked” array. I will also include a running solution at the end.

Here’s the upated Person Class:

public class Person {
    protected string _firstName;
    protected string _lastName;
    protected string _midName;
    protected DateTime _dob;
    protected decimal[] _hoursWorked;

    public Person(string firstName, string lastName, string midName, DateTime dob) {
        _firstName = firstName;
        _lastName = lastName;
        _midName = midName;
        _dob = dob;
        _hoursWorked = new decimal[7];
    }
    public string FirstName {
        get { return _firstName; }
    }
    public string LastName {
        get { return _lastName; }
    }
    public string MiddleName {
        get { return _midName; }
    }
    public DateTime DateOfBirth {
        get { return _dob; }
    }
    public decimal this[int day] {
        get { return _hoursWorked[day]; }
        set { _hoursWorked[day] = value; }
    }
}

The only change is the addition of the _hoursWorked member and the indexor property to allow getting and setting the values of _hoursWorked. Now to the good stuff. The method I demonstrated in the last post required me to create new subclasses of PropertyDescriptor for each type of component I wanted to work with. DynamicPropertyDescriptor uses anonymous methods to provide a reusable implementation of the PropertyDescriptor class. Here’s what the new view code looks like:

public class PersonFullNameAgeHoursView : IPersonViewBuilder {
    public PropertyDescriptorCollection GetView() {
        List<PropertyDescriptor> props = new List<PropertyDescriptor>();

        props.Add(new DynamicPropertyDescriptor(
            typeof(Person),
            "FullName",
            typeof(string),
            delegate(object p) { 
                return ((Person)p).FirstName + " " 
                    + ((Person)p).MiddleName + " " 
                    + ((Person)p).LastName; },
            null
        ));

        props.Add(new DynamicPropertyDescriptor(
            typeof(Person),
            "Age",
            typeof(string),
            delegate(object p) {
                return DateTime.Today.Year - ((Person)p).DateOfBirth.Year;
            },
            null
        ));

        for ( int day = 0; day < 7; day++ ) {
            // without this variable declared inside the loop, 
            // the anon methods won't work correctly
            // they will all reference the value of the 
            // foreach loop variables as set on the last iteration
            int bindableDay = day;
            props.Add(new DynamicPropertyDescriptor(
                typeof(Person),
                Enum.GetName(typeof(DayOfWeek), day),
                typeof(Decimal),
                delegate(object p) { 
                    return ((Person)p)[bindableDay];
                },
                delegate(object p, object newPropVal) { 
                    ((Person)p)[bindableDay] = (decimal) newPropVal; 
                }
            ));
        }


        PropertyDescriptor[] propArray = new PropertyDescriptor[props.Count];
        props.CopyTo(propArray);
        return new PropertyDescriptorCollection(propArray);
    }
}

Pay very close attention to the bindableDay variable. This whole thing would have been a piece of cake if not for that little issue. If you want to have a deep understanding of the issue, take a look at this post that explains how anonymous methods are implemented and this post that details the issue of generating anonymous methods that reference local variables in a loop.

Here’s the result of binding PersonCollection to a DataGridview (note that I typed the hour values into the grid, they did not come from the source):

Demo Output

Click here for a complete VS2005 solution.

I haven’t done any performance comparisons between using this method versus type specific subclasses other than to see that was “fast enough” for what I was using it for. However, in performance critical scenarios, you may want to go with the other method.

Follow

Get every new post delivered to your Inbox.