Archive

Posts Tagged ‘c#’

Revisit Dynamic Event Handler in .NET

July 11th, 2012 Comments off

A while ago I blogged about how to build a catch-all handler for .NET events and delegates. That solution uses LCG to generate CIL for the dynamic delegate. The latest version of Fasterflect however uses Expression Trees to generate the dynamic delegate. So I thought I would post the new solution here for completeness.

Training screen casts (in Vietnamese) about C#, ASP.NET MVC, LINQ and Combres

August 15th, 2011 7 comments

The series of MVC/C#/LINQ/Combres screen-casts (in Vietnamese) I produced for Microsoft Vietnam a while a go. Microsoft Vietnam recently allowed CiOne to distribute on their website so that everyone can access for free.

C# Training for Microsoft Customers

June 16th, 2011 1 comment

Slides for the C# training I conducted for Microsoft’s customers in Ho Chi Minh city on June 9th 2011. The training covered C# 3.0, LINQ, C# 4.0 and Dynamic Binding.

Some pictures of the training
Me

Me

Me

A catch-all .NET delegate and event handler

April 15th, 2011 Comments off

In a current project, I need to build a catch-all handler which could be used to wired to any static or instance delegate and event regardless of the actual delegate/event type.

For example, given the following definitions:

    
private delegate int Op(int i);
private delegate int BinaryOp(int i, int j);
class Test
{
    public Op OpDelegate;
    public event BinaryOp BinaryEvent;
}

I want to be able to write code like this:

    
obj.AddHandler("OpDelegate", args => (int)args[0] * (int)args[0]);
obj.AddHandler("BinaryEvent", args => (int)args[0] + (int)args[1]);

In the above code segment, code>obj is an instance of the Test class. AddHandler should be an extension method for object class. The parameters include the name of the delegate or event and a catch-all handler of type Func<object[], object> and this handler might have been bound to some target. In addition, the code in question mustn't need to know about the actual type of obj at compile time nor does it need to know about the actual signature of the delegate and event being wired.

What AddHandler needs to do is creating some delegate matching the definition of the delegate/event being wired and have that delegate forward the call to the Func<object[], object> argument. That calls for a bit of code generation to build a delegate instance from a runtime generated method definition (which will have its signature match the delegate/event being wired). Like when developing Fasterflect, I opt for CIL generation.

The code for the solution is below. I will incorporate it into Fasterflect as an add-on service. Note that it makes use the EmitHelper class which could be found here.

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using Emitter;

public static class DynamicHandler
{
    public static Type AddHandler(this Type targetType, string fieldName,
        Func<object[], object> func)
    {
        return InternalAddHandler(targetType, fieldName, func, null, true);
    }

    public static Type AssignHandler(this Type targetType, string fieldName,
        Func<object[], object> func)
    {
        return InternalAddHandler(targetType, fieldName, func, null, false);
    }

    public static Type AddHandler(this object target, string fieldName,
        Func<object[], object> func)
    {
        return InternalAddHandler(target.GetType(), fieldName, func, target, true);
    }

    public static Type AssignHandler(this object target, string fieldName,
        Func<object[], object> func)
    {
        return InternalAddHandler(target.GetType(), fieldName, func, target, false);
    }

    private static Type InternalAddHandler(Type targetType, string fieldName,
        Func<object[], object> func, object target, bool combine)
    {
        Type delegateType;
        var eventInfo = targetType.GetEvent(fieldName);
        if (eventInfo != null && !combine)
            throw new ArgumentException("AssignHandler cannot be used for event type");

        if (eventInfo != null)
        {
            delegateType = eventInfo.EventHandlerType;
            var dynamicHandler = BuildDynamicHandler(targetType, delegateType, func);
            eventInfo.GetAddMethod().Invoke(target, new Object[] {dynamicHandler});
        }
        else
        {
            var fieldInfo = targetType.Field(fieldName,
                                                target == null
                                                    ? Flags.StaticAnyVisibility
                                                    : Flags.InstanceAnyVisibility);
            var field = !combine ? null : target == null
                                            ? (Delegate) fieldInfo.Get()
                                            : (Delegate) fieldInfo.Get(target);
            delegateType = fieldInfo.FieldType;
            var dynamicHandler = BuildDynamicHandler(targetType, delegateType, func);
            field = field == null
                        ? dynamicHandler
                        : Delegate.Combine(field, dynamicHandler);
            (target ?? targetType).SetFieldValue(fieldName, field);
        }
        return delegateType;
    }

    public static Delegate BuildDynamicHandler(this Type delegateOwnerType, Type delegateType, 
        Func<object[], object> func)
    {
        MethodInfo invokeMethod = delegateType.GetMethod("Invoke");
        Type returnType = invokeMethod.ReturnType;
        bool hasReturnType = returnType != Constants.VoidType;
        var paramTypes = invokeMethod.GetParameters().Select(p => p.ParameterType).ToArray();
        var dynamicMethod = new DynamicMethod("add_handler",
                                                hasReturnType ? returnType : null, 
                                                new [] {typeof(Invoker)}.Concat(paramTypes).ToArray(),
                                                delegateOwnerType);
        var il = new EmitHelper(dynamicMethod.GetILGenerator());
        il.ldarg_0.end(); // <this>
        il.DeclareLocal(typeof(object[])); 
        il.ldc_i4(paramTypes.Length); // <this> <length>
        il.newarr(typeof(object)); // <this> <arr>
        il.stloc_0.end(); // <this>
        for (int i = 0; i < paramTypes.Length; i++)
        {
            il.ldloc_0 // <this> <arr>
                .ldc_i4(i) // <this> <arr> <i>
                .ldarg(i + 1) // <this> <arr> <i> <arg_i+1>
                .boxIfValueType(paramTypes[i]) // <this> <arr> <i> <boxed_if_value:arg_i+1>
                .stelem_ref.end(); // <this> 
        }
        il.ldloc_0.end(); // <this> <arr>
        il.callvirt(Invoker.InvokeMethodInfo); // <ret>
        if (hasReturnType)
            il.unbox_any(returnType).ret();
        else
            il.pop.ret();
        return dynamicMethod.CreateDelegate(delegateType, new Invoker(func));
    }

    public class Invoker
    {
        public static readonly MethodInfo InvokeMethodInfo =
            typeof(Invoker).Method("Invoke", Flags.InstanceAnyVisibility);
        private readonly Func<object[], object> func;

        public Invoker(Func<object[], object> func)
        {
            this.func = func;
        }

        public object Invoke(object[] args)
        {
            return func(args);
        }
    }
}
Categories: .NET Tags: , , ,

C# 4.0 Dynamic Binding at BarCamp Saigon 2010

December 13th, 2010 Comments off

I hugely enjoyed BarCamp Saigon 2010 which took place yesterday at RMIT University.  Learned a lot of things and met great people.

Below is the slidedeck I used for my session.  Source code is here.

Handle all uncaught exceptions thrown when using Task Parallel Library (take 2)

May 7th, 2010 3 comments

A couple of days ago I posted a solution to handle all uncaught exceptions when using TPL. I’ve found a better way to do that, making use of task continuation. The class ThreadFactory below exposes the Error event which can be subscribed by a top-level handler and provides methods to start a task attached with proper continuation.

internal class ThreadFactory
{
    public delegate void TaskError(Task task, Exception error);

    public static readonly ThreadFactory Instance = new ThreadFactory();

    private ThreadFactory() {}

    public event TaskError Error;

    public void InvokeError(Task task, Exception error)
    {
        TaskError handler = Error;
        if (handler != null) handler(task, error);
    }

    public void Start(Action action)
    {
        var task = new Task(action);
        Start(task);
    }

    public void Start(Action action, TaskCreationOptions options)
    {
        var task = new Task(action, options);
        Start(task);
    }

    private void Start(Task task)
    {
        task.ContinueWith(t => InvokeError(t, t.Exception.InnerException),
                            TaskContinuationOptions.OnlyOnFaulted |
                            TaskContinuationOptions.ExecuteSynchronously);
        task.Start();
    }
}
Categories: .NET Tags: , , ,

Handle all uncaught exceptions thrown when using Task Parallel Library

May 4th, 2010 2 comments

I’m using the TPL (Task Parallel Library) in .NET 4.0. I want to be able to centralize the handling logic of all unhandled exceptions by using the Thread.GetDomain().UnhandledException event. However, in my application, the event is never fired for threads started with TPL code, e.g. Task.Factory.StartNew(...). The event is indeed fired if I use something like new Thread(threadStart).Start().

This MSDN article suggests to use Task#Wait() to catch the AggregateException when working with TPL, but that is not I want because it is not “centralized” enough a mechanism.

I’ve posted the above issue (verbatim) in this StackOverflow question but didn’t receive any response. So, I had to roll out some custom code to do that. Below is the description of the solution for those who are interested.

The general idea is pretty simple. First, we need to know all the currently executed tasks. Since there’s no built-in way to know which tasks are being executed, we need to intercept the task addition. The class TaskFactoryWrapper below does just that.

static class TaskFactoryWrapper
{
    public static void Start(Action action)
    {
        var task = new Task(action);
        TaskErrorWatcher.Instance.AddTask(task);
        task.Start();
    }

    public static void Start(Action action, TaskCreationOptions options)
    {
        var task = new Task(action, options);
        TaskErrorWatcher.Instance.AddTask(task);
        task.Start();
    }
}

Inside the class TaskErrorWatcher, there’s a worker thread which periodically checks each task to see if the latter already finishes, is canceled or causes an error. If it causes an error, the worker thread trigger the error event.

class TaskErrorWatcher
{
    public delegate void TaskError(Task task, Exception error);
    private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    private static readonly TaskErrorWatcher @Instance = new TaskErrorWatcher();

    public static TaskErrorWatcher Instance
    {
        get
        {
            return @Instance;
        }
    }

    private TaskErrorWatcher()
    {
        Task.Factory.StartNew(Monitor);
    }

    public event TaskError Error;

    public void InvokeError(Task task, Exception error)
    {
        TaskError handler = Error;
        if (handler != null) handler(task, error);
    }

    private readonly List<Task> tasks = new List<Task>();
    private readonly object syncLock = new object();

    public void AddTask(Task task)
    {
        lock (syncLock)
        {
            tasks.Add(task);
        }
    }

    private void Monitor()
    {
        Utils.Interval(3000, () =>
                                {
                                    lock (syncLock)
                                    {
                                        for (int i = tasks.Count - 1; i >= 0; i--)
                                        {
                                            var task = tasks[i];
                                            if (task.IsFaulted)
                                            {
                                                InvokeError(task, task.Exception);
                                            }
                                            if (task.IsCanceled || task.IsCompleted)
                                            {
                                                tasks.RemoveAt(i);
                                            }
                                        }
                                    }
                                },
                                ex => Log.Error(ex));
    }
}

Utils.Interval is simply a helper method which repeatedly executes an action when the specified interval has elapsed.

public static void Interval(long interval, Action action, Action<Exception> errorHandler = null)
{
    var watch = Stopwatch.StartNew();
    while (true)
    {
        try
        {
            action();
            watch.Stop();
            Thread.Sleep((int)Math.Max(0, interval - watch.ElapsedMilliseconds));
            watch.Restart();
        }
        catch (Exception ex)
        {
            if (errorHandler == null)
                throw;
            errorHandler(ex);
        }
    }
}

Now, in the top level code (e.g. inside Main()), just subscribe to the Error event of TaskErrorWatcher and do whatever you want to do in case of error, e.g.

TaskErrorWatcher.Instance.Error += (_, error) => HandleError(error);

That’s it. Hope it helps!

Speaking at the Visual Studio.NET 2010 Launch in Hanoi

April 19th, 2010 9 comments

Last Tuesday, I spoke at the Visual Studio.NET 2010 launch in Hanoi. It was a big launch with about 400 attendees. I hosted 2 sessions, one about ASP.NET 4.0 (including web forms, MVC, AJAX and dynamic data) and another about C# 4.0 and PLINQ. On the following day, I spoke at Microsoft Vietnam’s office about building scalable .NET web applications to about 40 .NET architects and developers in Hanoi.

In general, it was a great trip to Hanoi and I had a lot of fun speaking and meeting many people there. The sessions by other speakers were really great. I was particular impressed with what Silverlight 4.0 and SharePoint 2010 had to offer.

You can find the slides and sample code I used for these sessions below.

Sample code can be downloaded here

Some pictures taken (click to view larger images)

VS.NET 2010 Launch Event

Tea Break during the VS.NET 2010 Launch

.NET Web Scalability Presentation at Microsoft Vietnam's Office

Tea Break during the Scalability Presentation

Fasterflect 2.0 Release

March 21st, 2010 5 comments

I am pleased to announce the release of Fasterflect 2.0. For those who are not aware of Fasterflect, it is a library that helps you get rid of the complexity and slow performance of .NET Reflection. Check out this Code Project article and a previous announcement for an introduction.

Fasterflect 2.0 comes with a great number of additions & changes, which are possible thanks to the fact that I am no longer the only developer of this project; instead, Morten Mertner (author of Gentle.NET) has joined me since the beginning of 2.0 and made huge contribution ever since. Let’s look at some highlights of this release.

The most exciting addition in this release is that Fasterflect now includes a Query API. Previously you can only use Fasterflect to construct objects or performs invocations (these 2 usages are now referred as Access API). With this release, you can query .NET reflection metadata with Fasterflect although much simpler than what you have to do with the built-in .NET reflection. You can even do more thing with this Query API than you can with .NET reflection out of the box. For example, you can choose to exclude backing members from a lookup or enable partial-name lookup. All you need to do in order to have these level of control is specifying a proper Fasterflect binding flag. The nice thing about Fasterflect binding flag is that it is also fully supported in the Access API.

Next, the Access API is now fully integrated with .NET reflection metadata classes, such as ConstructorInfo, MethodInfo, FieldInfo etc. This integration makes it able for you to mix & match the usages of Query API and Access API as well as allows you to use .NET reflection as it is while delegating the invocation to the fast CIL-generation engine of Fasterflect.

We have also built on top of the core Fasterflect engine some add-on services such as advanced object construction, deep cloning and object mapping. We expect to have more of these services in future releases and of course, you can send us your contributions too.

Users of previous versions of Fasterflect should be aware of the following breaking changes.

  • Many existing extension methods have their names changed as we went through the process of improving API’s consistency & usability. We hope these changes are for the better because now we have 2 developers vote on the conventions instead of 1 like previously :-) . You would have to make some code change when switching from 1.1 to 2.0, but the changes should be very straight-forward in most cases except for the other changes described below.
  • Fasterflect extension methods now don’t require a type parameter, which we have found to be inconvenient because people are forced to append <object> to the call even when they don’t care about the return value or its type. These methods now simply return result of type System.Object and you can cast to the correct type if you need to.
  • Batch fields/properties setting are gone. They are replaced by the object mapping add-on service which is more flexible, sophisticated and faster (CIL code generation is used behind the scene). Batch setting of static members is not supposed though because we think it’s not a common scenario. That said, do let us know if you have this need and we will add support for it in the next minor release.
  • The class Reflector and its methods are now gone. We instead employ a custom-built weak reference-based cache to assure that generated CIL can be garbage-collected when memory is low.

Last but not least, the project wiki on CodePlex is fully populated with comprehensive documentation. While Fasterflect is still ridiculously easy to use, it now has a much bigger API and is more sophisticated than it used to be (e.g. with Fasterflect binding flags). Therefore, documentation should be of great help for those who want to understand everything about Fasterflect to use it effectively in even advanced scenarios without having to dig through the source code.

You can download the binary, source code and CHM API help file in the Fasterflect 2.0 release page in CodePlex. If you want to explore Fasterflect in details, surf through the project wiki. If you just want to jump right into the usages without any further introduction, check out the 2-minute-guide to Access API and this page about the Query API. Finally, the comprehensive unit test suite included in the code download can also serve as good reference for the API.

Fasterflect vs. C# 4.0 Dynamic

December 31st, 2009 4 comments

As .NET 4.0 final release will hit the market pretty soon, it’s worth discussing the value of Fasterflect in the face of C# 4.0′s dynamic keyword.  (If you aren’t familiar with C# 4.0 dynamic, you should read my article on C# 4.0 before continuing.)

To recall, Fasterflect was designed to address 2 key disadvantages of .NET Reflection: ease of use and performance.  As seen in my article about C# 4.0, the dynamic keyword nicely addresses the easy of use with a resulting syntax looking even nicer than Fasterflect.  How about performance?

I improved the benchmark application of Fasterflect to add some benchmark code comparing between the performance of C# 4.0 dynamic and Fasterflect.  Here is result of method invocation benchmark.

fasterflectbenchmark

While performing slower than Fasterflect’s cached API, C# dynamic performs much better than Fasterflect’s standard API.  (Not surprisingly, the C# dynamic binding doesn’t resort to the slow reflection mechanism internally.)

With this awareness in mind, together with the understanding about the features of C# dynamic and Fasterflect, let’s discuss about areas where Fasterflect shines even in the face of C# 4.0 dynamic:

  • C# dynamic doesn’t handle invocations performed based on dynamic information (i.e. field name read from XML file).
  • C# dynamic does handle certain types of dynamic invocations, including static method invocation, static property invocation and constructor invocation.
  • C# dynamic doesn’t handle non-public members.  So you’ll receive exception if trying to, say, invoke a private method.
  • When performance is more critical than readability then the Fasterflect’s cached API might be favored over C# dynamic.

Granted, there should be workarounds for the first 3 items.  For example, if you want to invoke static method dynamically with C# dynamic, you would have to workaround like the approach described in this article.  However, the approach uses reflection behind the scene so you would have the same performance issue to start with.

This doesn’t say that Fasterflect is better than C# dynamic though.  While both share a couple of features and maybe used interchangeably in some scenarios, they also have different problems of their own to address.  There are many things that you can do with C# dynamic that you couldn’t do with Fasterflect, e.g. implementing an interceptor to dynamically handle all method invocations (or missing methods) etc.  So, pick the right tool for your problem at hand.

Categories: .NET Tags: , , ,