Async in C#6

Async in C#6 – Simple example

When you have a large amount of data to be loaded, you won’t be able interact with the window – even to move it around – until the loading is complete. Unless the loading task is done asynchronously. Doing this used to require hundreds of lines describing state machines and so on – Jon Skeet gives a good account of this in his Pluralsight course on Async.

I like his example of the pizza delivery as the means of explaining asynchrony – you order your meal over the phone but don’t hang about at the front door waiting, you go get the dishes ready. Here, we order our data and setup our display whilst it arrives.

Below, is the results of a couple of hours scrapping with syntax to achieve the same result in a toy WPF app. Here, I’ve got a 120 superheroes, belonging to classes who are assigned random grades for several subjects. The notion came from an early morning drill where I was exploring how quickly could I throw a small object hierarchy together from an external source.

The original code is here though likely to be added to as I use other drills on it. Note the use of $ string interpolation rather than string.format – a nice new feature.

A non lambda version, requiring the use of the Async/Await in the main method body itself. And an alternative that hides this requirement completely inside a lambda of it’s very own. Basically you can declare a lambda to be async using the following syntax: async()=> await SomeTask()

 /// <summary>
    /// Non lambda version, the methods have to be async
    /// </summary>
    async void getHereosTask2()
        {
        Wilma.Text = await getHeroes2();
        }


    async Task<string> getHeroes2()
        {
        return await Task.Run(() =>
        {
            StringBuilder sb = new StringBuilder();
            foreach (StudentClass c in School.SuperHeroSchool)
                {
                sb.Append($"Class Name: {c.Name} \nDate:{DateTime.Today.ToShortDateString()}\n");
                foreach (Student student in c.Students)
                    {
                     sb.Append($"\n*** {student.Name}***\n");
                    foreach (var grade in student.Grades)
                        {
                        sb.Append($"{grade.Key} : {grade.Value} \n");
                        }
                    }
                }
            return sb.ToString();
        });
        }

Lambda style:

 /// <summary>
    /// Async style one: here we hide the need for the async inside lambdas :)
    /// Notice how the second method, Task<string> is NOT async.  Instead we just make a nice async lambda lambada!
    /// </summary>
      void getHereosTask()
        {
          Task<string> sb = Task.Run(async() => await getHeroes());
          Wilma.Text = sb.Result;
        }

       Task<string> getHeroes()
        {
        return Task.Run(() =>
        {
            StringBuilder sb = new StringBuilder();
            foreach (StudentClass c in School.SuperHeroSchool)
                {
                sb.Append($"Class Name: {c.Name} \nDate:{DateTime.Today.ToShortDateString()}\n");
                foreach (Student student in c.Students)
                    {
                    sb.Append($"\n*** {student.Name}***\n");
                    foreach (var grade in student.Grades)
                        {
                        sb.Append($"{grade.Key} : {grade.Value} \n");
                        }
                    }
                }
            return sb.ToString();
        });
        }

Final note: at a later stage, an F# version will be done just to practice crossing the idioms over! 🙂

Dynamic Rules engine – update

As an exercise in working with C#, I decided it was time I translated my dynamic rules engine over from VB.

Here is the translated Github gist: C# Dynamic Rules Engine

A rules engine itself is a useful concept for many scenarios, business rules, validation, filtering and more.

At the time I wrote this, I was working with legacy code, no ORM for the database – and classes generated from underlying database tables. It was a class per table, nothing more complex than this.

An operation was performed – by a third party – to merge 2 databases into 1. However, we couldn’t rely on the primary key that was in use any more. A proportion of records had their keys replaced. Not an ideal scenario but it was what we had.

A method of fact checking our table rows was required as various transformations were applied, in code, to try and line up the relationships to child tables in the database. Please note, there were no foreign key constraints either.

As a novice programmer (when does one come out of that title?), I figured that I could help – a little – if there was a way to show a row from a table in database 1 was the same as a row in the matching table in database 3 (the merged database). The only solution I saw at the time was fact checking columns. This required human intervention and knowledge of the data, which I had. About 12 critical tables were involved.

The aim of the game was to create a definition of the members (representing columns) that must match both sides for any row to be a match for it’s twin in the other database’s table. For example: a name, an address and an NI was enough to say this record for a person is the same on both sides. But a name and address was less certain.

As an exercise, I elected to work on this at home and learn what I could to find the neatest way to do this dodgy sounding task.

In the process I covered generics, interfaces, reflection and expression trees. That was a Friday evening – I was done by 2am.

The code worked, we were able to test it out on a number of cases and found that 99% of the data was fine, the rest was easily bought into line.

There’s a long list of reasons why such fact checking, in the way I describe here, is not a good idea. However, as an exercise in learning the programming concepts covered, I still am pleased with the original code. An F# version is likely to be a touch shorter – especially if I attempt it functionally!

Last caveat: The human aspect of having to know the columns means this is unviable for most scenarios and I regard the approach as a piece of throwaway code. Also, it could be argued as too complex a solution for the task at hand. Especially with the performance cost of the amount of reflection used.

The snippet below is the heart of the code:

/// <summary>
    /// The Dynamic Rules Engine itself
    /// Here we have to pass in a class instance and the properties to be matched.
    /// using reflection to get the members, put them in a list and generate a list of lambda predicates expressions
    /// We compile and run these - they all have to be true to get a match. We return a match item, if one exists.
    /// </summary>

    private T getMatchingMerge(T item, List<PropertyInfo> matchProperties)
        {
        List<PropertyInfo> getPropList = item.GetType().GetProperties().Where(s =>
                       s.Equals(matchProperties.Where(x => x.Name == s.Name).FirstOrDefault())).ToList();
        if (propDict.Count < matchProperties.Count)
            {
              propDict = getPropList.ToDictionary(p => matchProperties.Where(s => s.Name == p.Name).First());
            }

        if (_rules.Count != matchProperties.Count) {
            _rules.Clear();  
            foreach (var lambda in from Pair in propDict
                                   let leftProperty = Pair.Key
                                   let rightProperty = Pair.Value
                                   let leftParameter = Expression.Parameter(rightProperty.DeclaringType, rightProperty.DeclaringType.Name)
                                   let rightParameter = Expression.Parameter(rightProperty.DeclaringType, rightProperty.DeclaringType.Name)
                                   let left = Expression.Property(leftParameter, leftProperty)
                                   let right = Expression.Property(rightParameter, rightProperty)
                                   let leftEqualsRight = Expression.Equal(left, right)
                                   // select Expression.Lambda<Func<T, T, bool>>(leftEqualsRight, Expression), new Parameter.Expression() { leftParameter, rightParameter }).Compile()
                                   select Expression.Lambda<Func<T, T, bool>>((Expression)leftEqualsRight, new ParameterExpression[] { leftParameter, rightParameter }).Compile())
                _rules.Add(lambda);
        }
        T _match = MergeList.Where(r => _rules.All(x => x.Invoke(item, r) == true)).FirstOrDefault();
        return _match; //I've not covered the path where there is no match!
     }

C# Dynamic Rules Engine