Managed World

Techno-babble from yet another babbler RSS 2.0
# Thursday, September 18, 2008

I've talked in the past about the importance of parallel computing for all us developers. It's a trend in computer software and hardware architecture that is not a fad. Currently, in the US, it is nearly impossible to buy a new computer that has only a single core. We're even starting to see some of the first quad-core laptops hit the market.

It's becoming very important for developers to start dealing with parallel code. There's one problem: multithreaded development is hard. And in the class of Threading 101, Race Conditions is one of the first chapters you have to deal with.

So what is a Race Condition? According to Wikipedia, the source for all information on the Internet (emphasis mine):

"A race condition, or race hazard, is a flaw in a system or process whereby the output and/or result of the process is unexpectedly and critically dependent on the sequence or timing of other events. The term originates with the idea of two signals racing each other to influence the output first."

That's nice and all, but what does this mean to us developers? Let's look at a simple example. I have a Logger where I want to keep track of the number of messages that are logged.

   1: class Logger
   2: {
   3:     public static int TotalMessages = 0;
   4:  
   5:     public void Log(string message)
   6:     {
   7:         // Do something with message
   8:         TotalMessages++;
   9:     }
  10: }

Now let's call this method a bunch of times from four different threads and capture the total number of times Log message was called:

   1: int messagesPerTask = 200000;
   2: int unitsOfWork = 4;
   3:  
   4: var logger = new Logger();
   5: Parallel.For(0, unitsOfWork, (taskNumber) =>
   6: {
   7:     for (int i = 0; i < messagesPerTask; i++)
   8:     {
   9:         logger.Log("Message " + i.ToString());
  10:     }
  11: });
  12:  
  13: Console.WriteLine("{0} Expected", messagesPerTask * unitsOfWork);
  14: Console.WriteLine("{0} Actual", Logger.TotalMessages);

What do you expect the output to be? The obvious answer is "well, we are adding 200000 messages on four different threads, so it's obviously 800000". Unfortunately, the obvious answer also happens to be the wrong answer. What's the right answer? It depends, and it can change every single time you run the application. For example, this were the results from the first time I ran the code:

800000 Expected
680354 Actual

Wait... how is this possible? Did we lose updates? Did I not call the method enough times? This surely must be a horrendous bug in the .NET Framework! Damn Bill and his blasted company. Trust me, it's not a bug. There's a good explanation of this behavior.

If you haven't written a lot of multithreaded code yet, the problem with the above code may not be obvious. Truth be told, there really isn't a problem with the code... IF you are only running the code on a single thread ever. But the likelihood of running on a single thread is becoming smaller and smaller. And as you can see, when we are running this in a multithreaded environment, there is most definitely a problem with the code.

A lot of .NET developers look at "TotalMessages++" and interpret it as one line of code, one execution, one instruction, etc. But there's the rub, it isn't. The code "TotalMessages++" is actually four instructions when compiled down to IL.

   1: L_0001: ldsfld int32 CSharpSandbox.Logger::TotalMessages
   2: L_0006: ldc.i4.1 
   3: L_0007: add 
   4: L_0008: stsfld int32 CSharpSandbox.Logger::TotalMessages

These four lines essentially say the following:

  1. Get the current value of TotalMessages
  2. Get the value 1
  3. Add the two numbers together
  4. Save the result back into TotalMessages

Now let's imagine two threads executing the four steps above at the same time. Since threads won't be in perfect lock-step, they may be off by two steps (assuming the value of TotalMessages is currently 2):

[Thread 1] 1. Get the current value of TotalMessages (gets 2)
[Thread 1] 2. Get the value 1

[Thread 2] 1. Get the current value of TotalMessages (gets 2)
[Thread 2] 2. Get the value 1

[Thread 1] 3. Add the two numbers together (2 + 1)
[Thread 1] 4. Save the result back into TotalMessages (saves 3)

[Thread 2] 3. Add the two numbers together (2 + 1)
[Thread 2] 4. Save the result back into TotalMessages (saves 3)

So we've executed that code twice and at the end of the execution, TotalMessages has only increased by one. This is exactly what a race condition is. It's that simple. It's not as advanced as a concept as one might think.

This is why developers need to understand what race conditions are. A snippet of code that looks completely innocuous can cause some big problems when run in a multithreaded development. While future technologies will make writing parallel code easier, it won't prevent these types of problems from occurring. You still need to be aware of some of the common Threading 101 concerns/topics that exist today.

 #       Comments [4]
# Friday, July 04, 2008

How would you like to use the following way to configure dependencies in MEF? A fluent interface with POCO support (no attributes necessary)? Yup.

            var resolver = new FluentResolver();
            resolver.Register<HelloWorld>().
                And<HelloGreeting>().As<IGreeting>().
                And<ConsoleOutputter>().As<IOutputter>();

            var domain = new CompositionContainer(resolver);

            // HelloWorld has dependencies on IGreeting and IOutputter
            var helloWorld = domain.Resolve<HelloWorld>();
            helloWorld.SaySomething();

Lately I've been digging more and more into the first CTP of the Managed Extensibility Framework (MEF) coming out of Krzysztof Cwalina's team here at Microsoft. By default, a developer needs to sprinkle Export and Import attributes in their classes at the point they are needing something to be injected, or on classes that need to be exported in order to be injected into other classes. However, if you don't like this behavior, MEF provides several extension points you can use to provide a different interface into MEF.

In my "ideal" Dependency Injection interface for MEF, there are several requirements that I would like:

  • No Export/Import attributes necessary; hence, support for POCOs (Plain Ol' CLR Objects)
  • Registration of types with container, not registration of object instances (where I would have to create the object myself before adding it's type to the container).
  • Simply ask container to resolve a type into an instance for me. Other than the container and resolver, none of my "domain objects" should be "new"-ed up by me.
  • No need to tell the CompositionContainer to Bind(). It should know about all the types necessary.
  • For "ease of use", I want to configure dependencies via a Fluent Interface.

I'm on a little bit of a Fluent Interface kick right now. I admit it. My name is Jason Olson and I'm a Fluent Interface junkie. If I could type emails via a Fluent Interface in code (rather than Outlook), I probably would. My addiction is just... that... bad.

Before we dig into how we will leverage MEF's extension points, let's just take a quick peek at the classes we are wanting to wire up via the interface shown above:

    class HelloWorld
    {
        public IGreeting Greeting { get; set; }
        public IOutputter Outputter { get; set; } 

        public void SaySomething()
        {
            // Our dependencies above determine where the output
            // is written to, and what the greeting will be.
            Outputter.WriteLine(Greeting.Greet());
        }
    }

    interface IGreeting
    {
        string Greet(); 
    }

    class HelloGreeting : IGreeting
    {
        public string Greet() 
        {
            return "Hello Fluent Interface!";
        }
    }

    interface IOutputter
    {
        void WriteLine(string message); 
    }

    class ConsoleOutputter : IOutputter
    {
        public void WriteLine(string message)
        {
            Console.WriteLine(message);
        }
    }

So how do we enable this new behavior? There are two primary MEF extension points we will use, a custom ComponentBinder and a custom ValueResolver. According to the CTP documentation (emphasis mine):

"The role of the ComponentBinder is to create a collection of primitives associated with its component. There is only one ComponentBinder per component. The CompositionContainer will use the collection of binders during the bind operation to determine how components need to be wired-up."

In this case, "collection of primitives" essentially means the export and imports of the component it is bound to. One of the interesting points to note is that the CompositionContainer uses these ComponentBinders to determine how various components need to be created. So for MEF to determine what the various imports and exports are for wiring up components, it can use our custom ComponentBinder to do so. So while the default ReflectionBinder will generate this information via attribute declarations on the components in question, we can change this behavior if we wish.

The other extension point we will use is a custom ValueResolver. Once again, according to the CTP documentation (emphasis mine):

"A ValueResolver allows the composition container to retrieve components from some sort of repository. The composition container’s bind operation has the single goal of satisfying all imports for all components that were explicitly added to it. During a bind operation, the composition container can query the ValueResolver for exports if it deems it necessary (e.g. no exports currently in the composition container satisfy a specific import, an import is requesting a collection of all available exports, etc.)."

To implement these two extension points, we will need two custom classes: FluentResolver and FluentBinder. Our FluentResolver is what we use to build up a map of our dependencies via the fluent interface shown above. When the FluentResolver is then passed into a CompositionContainer, we will go through our dependency map and crank out a bunch of FluentBinders that MEF can then use when needing to create various objects the user is asking for.

First, our FluentResolver. FluentResolver contains the methods that make up our fluent interface and that will hold the dependency map we are building up. And then we our FluentResolver is hooked up to a CompositionContainer, we will use this "dependency map" in order to build up all the FluentBinder instances that MEF will use to wire up all our dependencies.

    class FluentResolver : ValueResolver, IRegisterChainer
    {
        private Type lastRegisteredType;
        private IDictionary<Type, IList<Type>> exportTypes = new Dictionary<Type, IList<Type>>();
        private IList<Type> registeredTypes = new List<Type>();

        // The following three methods define our fluent interface
        // (Register<T>, And<T>, and As<T>).
        public IRegisterChainer Register<T>() where T : class, new()
        {
            if (!exportTypes.ContainsKey(typeof(T)))
            {
                exportTypes.Add(typeof(T), new List<Type>());
            }

            exportTypes[typeof(T)].Add(typeof(T));
            registeredTypes.Add(typeof(T));

            lastRegisteredType = typeof(T);
            return this;
        }

        public IRegisterChainer As<T>() where T: class
        {
            // Add exported type to last registered type (the call right
            // before .As<T>() in the fluent interface). This is used
            // to register a type as an interface, rather than the
            // concrete type.
            exportTypes[lastRegisteredType].Add(typeof(T));
            return this;
        }

        public IRegisterChainer And<T>() where T : class, new()
        {
            // Just a different way to register so that the fluent
            // interface is easily readable.
            return Register<T>();
        }

        // This is where the "magic" happens. When our container is set (like
        // when we are passed into the constructor of a container), we will
        // create all of our custom binders that MEF will then use to wire-up
        // dependencies.
        protected override void OnContainerSet()
        {
            base.OnContainerSet();

            foreach (var type in registeredTypes)
            {
                // An "Import" (read: injected dependency) is defined as any property whose
                // type is a type that is "exported" from any other registered type
                var imports = (from pi in type.GetProperties()
                               from export in exportTypes
                               where export.Value.Contains(pi.PropertyType)
                               select pi).Distinct();

                // Export all types our specific type has been asked to export and all the 
                // properties from above that are dependencies we need to inject.
                Container.AddBinder(new FluentBinder(type, exportTypes[type], imports.ToList()));
            }
            
            // Since all the dependencies are known from our fluent interface,
            // automatically bind the container so that the user doesn't have to
            // call Bind() themselves.
            Container.Bind();
        }

        public override CompositionResult<IImportInfo> TryResolveToValue(string name, IEnumerable<string> requiredMetadata)
        {
            // Same as TryResolveToValues below, except we just return a
            // single value, rather than a collection of values.
            var result = TryResolveToValues(name, requiredMetadata);

            return new CompositionResult<IImportInfo>(result.Succeeded, 
                result.Issues, 
                result.Value.First());
        }

        public override CompositionResult<ImportInfoCollection> TryResolveToValues(string name, IEnumerable<string> requiredMetadata)
        {
            // Based on all the custom binders we have created, have
            // the container get the various dependent components for us.
            return TryGetContainerLocalImportInfos(name, requiredMetadata);
        }
    }

IRegisterChainer is simply an interface our three fluent methods (Register<T>, And<T>, As<T>) return (and that FluentResolver implements) that allows us to keep on chaining our method calls one after the other, hence enabling our fluent interface.

    interface IRegisterChainer
    {
        // Allows registering another dependency into our resolver
        IRegisterChainer And<T>() where T : class, new();

        // Enables registering a depedency as a specific type (like
        // an interface) on top of the concrete type it directly implements
        IRegisterChainer As<T>() where T : class;
    }

And now on to our FluentBinder:

    class FluentBinder : ComponentBinder
    {
        // An instance of the type we are the binder for
        private object instance;

        // The types we export (could be our concrete type, interfaces, etc.)
        private IList<Type> exports;

        // Our properties that are dependencies needing resolving
        private IList<PropertyInfo> imports;
       

        public FluentBinder(Type type, IList<Type> exports, IList<PropertyInfo> imports) 
        {
            this.exports = exports;
            this.imports = imports;

            // In the future, we could use constructor injection here. For now,
            // just use the default constructor and property injection.
            instance = type.GetConstructor(new Type[] {}).Invoke(new object[] {});
        }


        public override IEnumerable<string> ExportNames
        {
            // Return the name of the Types we are Exporting
            get { return exports.Select(t => t.ToString()); }
        }

        public override CompositionResult Export() 
        {
            // Add our object instance into the container for every type
            // that we are exporting.
            foreach (var type in exports)
            {
                AddValueToContainer(type.ToString(), instance);
            }

            return new CompositionResult(true, new List<CompositionIssue>());
        }

        public override IEnumerable<string> ImportNames
        {
            // Return the name of the Types we need Imported
            get { return imports.Select(pi => pi.PropertyType.ToString()); }
        }

        public override CompositionResult Import(IEnumerable<string> changedValueNames) 
        {
            // Import every property we have that is a dependency
            foreach(var propertyInfo in imports)
            {
                // Inject an instance of the type of our property from the container
                var component = Container.TryGetBoundValue(propertyInfo.PropertyType.ToString(), 
                    propertyInfo.PropertyType);

                propertyInfo.SetValue(instance, component.Value, null);
            }

            return new CompositionResult(true, new List<CompositionIssue>());
        }
    }

This FluentBinder is essentially the heart of the our behavior. We use the the results from our FluentResolver that are passed in to our binder to let MEF know what types we need to import and what types we are exporting from the type FluentBinder is bound to.

The final thing we need to enable our desired API from above is an extension method to CompositionContainer called Resolve<T>() which we just give the type that we would like an instance of. I just happen to think this thin wrapper around TryGetBoundValue<T>() is easier to use and better to read.

    static class CompositionContainerExtensions
    {
        public static T Resolve<T>(this CompositionContainer domain)
        {
            return domain.TryGetBoundValue<T>().Value;
        }
    }

And now we can combine all the pieces together to build our sample application:

    class Program
    {
        static void Main(string[] args)
        {
            // Declare dependencies via a fluent interface.
            // No need for attributes, XML config, or 
            // registration of instances of objects.
            var resolver = new FluentResolver();
            resolver.Register<HelloWorld>().
                And<HelloGreeting>().As<IGreeting>().
                And<ConsoleOutputter>().As<IOutputter>();

            // Pass in our custom resolver and have it help
            // take care of the binding process.
            var domain = new CompositionContainer(resolver);

            // Ask the container for an instance of a type.
            var helloWorld = domain.Resolve<HelloWorld>();
            helloWorld.SaySomething();

            Console.ReadKey(true);
        }
    }

While the fluent interface might be seen as a potential "big departure" from the way MEF works out-of-the-box, you can see that it is very possible (and not too difficult) to change how dependencies are configured with MEF. You might want your configuration in an XML file, in a DSL defined in a map.txt file, in a database (no I don't know why you'd want that :P), etc. And no matter how you want it done, it is possible for you to do so with just a little coding.

Until next time, Happy Coding!

Obviously, this is just a sample prototype and doesn't have several features necessary in DI containers. So, more reason for me to write some more code :). Also, remember this is built on the first CTP of MEF, so the odds are that it will become out-of-date at a later time.

 #       Comments [21]
# Saturday, June 14, 2008

One realization I have come to when talking with many other developers is that there is a good number of developers that don't realize that inheritance introduces dependencies directly into your classes. Your derived class is now dependant upon the interface and behavior of your base class. Worded another way, your derived class is now strongly coupled to your base class. I've met a number of developers that are very passionate about managing their dependencies via inversion of control, dependency injection, etc. and yet they implement solutions that have a class hierarchy 5+ layers deep.

This strong coupling can become problematic if you need to change either the interface or behavior of my base class. For instance, if I need to add another abstract method I didn't originally think of, every single class that derives from that base class now must change in order to implement that behavior. Or, if I change the behavior of one of the methods in my base class, I can find myself in a situation where one of my derived classes will break because they were relying on that base class behavior to act a given way (even more confusing when the change doesn't impact any other of the derived classes).

Over-using (read: abusing) inheritance in your code can very easily lead to brittle classes that prevent you from being as agile as you need to be. While it is easy for developers to look at dependencies as other external classes your class is dependant upon, you have to keep in mind that your class is also strongly dependant on its base class as well.

The beautiful thing is that with some of the functionality introduced into .NET in both 2.0 and 3.5, you can avoid developing these brittle classes by using Generic programming.

"Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters. This permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication."

I know this description can be a bit confusing at first. Let's learn about Generic programming by example. And as an example, let's take a look at possible implementations of the Command pattern.

"In object-oriented programming, the Command pattern is a design pattern in which objects are used to represent actions. A command object encapsulates an action and its parameters."

In these examples, we are going to look at a home automation system. Specifically, let's look at the code it takes to automate lights using the Command pattern. In order to do this, we of course need a Light that we are actually automating (automation code removed for readability purposes):

    class Light
    {
        public void TurnOn()
        {
            Console.WriteLine("Light Turned On");
        }

        public void TurnOff()
        {
            Console.WriteLine("Light Turned Off");
        }
    }

So, let's dive right in.

In the "typical" way of implementing the Command pattern, you have an abstract base class Command that your detailed commands inherit from, overriding a virtual method to actually execute the command (this could also be an interface ICommand as well, instead of an abstract base class).

    abstract class Command
    {
        public abstract void Execute();
    }

    class LightOnCommand : Command
    {
        private Light _light;

        public LightOnCommand(Light theLight)
        {
            _light = theLight;
        }

        public override void Execute()
        {
            _light.TurnOn();
        }
    }

    class LightOffCommand : Command
    {
        private Light _light;

        public LightOffCommand(Light theLight)
        {
            _light = theLight;
        }

        public override void Execute()
        {
            _light.TurnOff();
        }
    }

Let's take another look at that definition of the Command pattern: "the Command pattern is a design pattern in which objects are used to represent actions". In our case, each action (turning a light on, turning a light off) is represented by an object (LightOnCommand, LightOffCommand).

Now to use these classes, all we need to do is instantiate new instances of our two commands (LightOnCommand and LightOffCommand) and execute them. Pretty simple. And because of leveraging a common base class, we can use polymorphism to reuse this code even more (like having a list of commands that we can execute in a script or elsewhere).

            var livingRoomLight = new Light();
            var lightOn = new LightOnCommand(livingRoomLight);
            var lightOff = new LightOffCommand(livingRoomLight);

            lightOn.Execute();
            lightOff.Execute();

This classic approach doesn't come without it's drawbacks though. First of all, for every home device that we wish to turn on and off, we would be introducing two new classes into our code. While this may not be that bad for a couple of devices, it can quickly get out of hand when the number of devices start to grow.

Also, the "common behavior" we get out of our base class isn't very flexible. If we change our Execute() method in our base class from abstract to virtual in order to introduce common behavior, how do you guarantee that the base method is called when it should be? In a derived class, should you call the base method before your own execution code, or after? What if I want common code in my base class that will be executed both before and after the behavior in my derived classes? While .NET has ways of achieving this, it quickly becomes complex and just introduces more code that obfuscates what the true purpose of our code is.

Not as flexible as we first though, eh?

So what has .NET done lately to make this job easier? Well, with the introduction of Generics and Lambdas, we can do a form of Generic programming that helps us write "one Command class to rule them all." By writing more generic code, you get down to the essence of what your code needs to do, and allows you to write code that is more flexible and not as dependant on other classes as before (since we are not directly leveraging inheritance like we were before).

What might a generic solution to the Command pattern look like?

    class GenericCommand<TReceiver>
    {
        private TReceiver _receiver;
        private Action<TReceiver> _commandToExecute;

        public GenericCommand(TReceiver theReceiver, Action<TReceiver> theCommandToExecute)
        {
            _receiver = theReceiver;
            _commandToExecute = theCommandToExecute;
        }

        public void Execute()
        {
            _commandToExecute(_receiver);
        }
    }

Let's look back at that description for Generic programming: "This permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication." That's all we are doing here. We have written a common type in which only the types on which it operates differs when used.

When we use this generic type is when we actually dictate what type it operates upon. In the case of our home automation system, we are going to create an instance of our GenericCommand that operates on a Light fixture. Then, we will specify what action needs to be taken when the command is execute by leveraging lambda expressions:

            var livingRoomLight = new Light();

            var genericLightOn = new GenericCommand<Light>(livingRoomLight, theLight => theLight.TurnOn());
            var genericLightOff = new GenericCommand<Light>(livingRoomLight, theLight => theLight.TurnOff());

Pretty simple, for our light on command we turn the light on, and for our light off command we turn the light off. And in both cases, we are using the exact same common type (GenericCommand<TReceiver>) when declaring our command.

Now let's say we want to start automating our Garage as well. The class we might be given to do this automating might look like the following (with all the automation code removed again):

    class Garage
    {
        public void TurnLightOn()
        {
            Console.WriteLine("Garage Light Turned On");
        }

        public void TurnLightOff()
        {
            Console.WriteLine("Garage Light Turned Off");
        }

        public void OpenDoor()
        {
            Console.WriteLine("Garage Door Opened");
        }

        public void CloseDoor()
        {
            Console.WriteLine("Garage Door Closed");
        }
    }

Using the prior inheritance-based way, we would need to introduce two more command classes for this new Garage automation. And as stated before, when having to introduce two more command classes for every new piece of home automation, we quickly have a blow-up in the number of classes we have to maintain. However, using the generic programming-based approach that leverages Generics and Lambdas, we actually don't have to introduce any new classes as our meta-class GenericCommand<T> can handle those situations already. 

Here's how we might consume the new Garage with our GenericCommand<T>:

            var genericOpenGarage = new GenericCommand<Garage>(myGarage, theGarage => 
            { 
                theGarage.TurnLightOn(); 
                theGarage.OpenDoor(); 
            });
            var genericCloseGarage = new GenericCommand<Garage>(myGarage, theGarage => 
            { 
                theGarage.CloseDoor(); 
                theGarage.TurnLightOff(); 
            });

            genericOpenGarage.Execute();
            genericCloseGarage.Execute();

Very simple. Once again, we are using the exact same type (GenericCommand<TReceiver>) to implement the automation commands for our Garage as we were using with our Light. So, the same common type that, when used, only differs by the types it operates on. Which is exactly the definition of Generic programming we discussed before. It's not as scary as it sounds!

Now if we need to introduce logging or any other common functionality into our command class, we can introduce it in one place and have it applied to all our consuming code. Unlike the polymorphic approach outlined above, we now have the flexibility in this approach to execute any common code in relation to our command, whenever we want, however we want. It doesn't matter if that common code is before, or after, or before and after.

If you are still reading this (in which case I thank you), you should realize that you are already familiar with a pattern used to achieve parallelism in the new Parallel Extensions to the .NET Framework CTP that has been released. The programming model used when dealing with Tasks and Futures are essentially the exact same thing as the generic command pattern used above. So if you grok the GenericCommand above, you'll settle right into using Tasks and Futures within the Parallel Extensions.

In closing, by using a Generic programming approach when implementing our Command pattern, we now have just the base functionality that is absolutely needed to implement our commands. And, we avoid the explosion in the number of classes and dependencies that taking an inheritance-based approach would introduce, all made possible by the introduction of Generics (in 2.0) and Lambdas (in 3.5) in .NET.

I hope you enjoyed this walk down the "applying generics and lambdas" road. Until next time, Happy Coding!

Posted in C# | Programming
 #       Comments [19]
# Thursday, June 12, 2008

In this post I want to discuss with you the importance of realizing how lambdas work (and why you should care). Let's dive right in with some code.

Given the following code snippet, what would you expect the output to be (no cheating :P)?

            var actions = new List<Action>();

            for (int i = 0; i < 10; i++)
            {
                actions.Add(() => Console.WriteLine(i));
            }

            foreach (var action in actions)
            {
                action();
            }

Would you believe me if I told you this is the output you get?

10
10
10
10
10
10
10
10
10
10

At first glance, one might expect this output:

0
1
2
3
4
5
6
7
8
9

But all tens are output instead. Why does this happen? Let's crank open Reflector and find out why...

 

The first thing you'll notice is that the compiler has created a helper class to enable the closure we have. This helper class created by the compiler contains a local variable that we use to iterate over and a method that our delegate is contained within. This helper class is especially interesting because it is where the magic happens.

 

[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
    // Fields
    public int i;

    // Methods
    public void <Main>b__0()
    {
        Console.WriteLine(this.i);
    }
}

Rather than diving into MSIL, let's look at some pseudo-code of what the compiler _actually_ executes with the original code above (based on the generated MSIL):

 

var actions = new List<Action>();

<>c__DisplayClass2 localFrame = new <>c__DisplayClass2();
for (localFrame.i = 0; localFrame.i < 10; localFrame.i++)
{
	actions.Add(localFrame.<Main>b__0);
}

foreach (var action in actions)
{
	action();
}

 

Perhaps now you can see where the problem is. The "problem" in our original code exists because of the scope that our closures are defined. The local index from our for loop is now stored in our helper class <>c__DisplayClass2. And the code that is executed by the action is contained within the compiler generated <Main>b__0() method now. So the Console.WriteLine() method now uses the local variable from <>c__DisplayClass2 when it is executed.

 

So while we are looping through building all our actions, we are also incrementing the property i in localFrame (an instance of <>c__DisplayClass2). Then at the end when we are actually executing the actions, the <Main>b__0() is called and uses the local i property (which by this time, has already been incremented to 10 from our loop). And that's why every action we execute prints "10" instead of the 0 through 9 like we expected.

 

So, why do you need to know how these work? Take the following code that outputs items from an array of strings:

 

            var actions = new List<Action>();
            string[] urls = 
            { 
                "http://www.url.com", 
                "http://www.someurl.com", 
                "http://www.someotherurl.com", 
                "http://www.yetanotherurl.com" 
            };

            for (int i = 0; i < urls.Length; i++)
            {
                actions.Add(() => Console.WriteLine(urls[i]));
            }

            foreach (var action in actions)
            {
                action();
            }

 

This code looks pretty innocuous. Our bounds are protected, and we just index into our array to output a string. But, is that what we're really doing? Remember how closures work from above. The actual thing that happens when I run this code is this:

 

Confusing

 

Interesting. Even though our index variable should only even be less than the length of our url array, an exception is thrown because the index variable is actually equal to the length of our url array (and hence outside of the bounds thanks to 0-based indices).

 

Well, that wasn't what we were probably expecting. But now that we are having this "problem", what is the easiest way to resolve it? Remember that the problem is happening because of the scope of the variable within our closure. So to fix this, we can essentially declare a temporary variable that is unique in scope to this specific iteration through our array:

 

            for (int i = 0; i < urls.Length; i++)
            {
                string localUrl = urls[i];
                actions.Add(() => Console.WriteLine(localUrl));
            }

 

And now the code is fixed.

 

Understanding how lambdas work is especially important when you start developing with a library that leverages lambdas heavily like LINQ does, or Parallel Extensions to the .NET Framework. And don't worry, even those people that know how lambdas work occasionally get bitten by this behavior.

 

Enjoy the coding, folks!

Posted in C# | Programming
 #       Comments [7]

Contact

Email Me Send mail to the author(s)

Calendar

<October 2008>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

About this site

Jason Olson's thoughts on Programming, Games, Music and Life in General

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Jason Olson

Sign In
All Content © 2008, Jason Olson
Theme based on 'Business' created by Christoph De Baene (delarou)