Unexpected results with Lambdas and Creating New Threads in C#

Today I was creating a simple application that needed to read from a queue and send XML to a web service.  It seemed to me to be a perfect opportunity to create a multi-threaded application.   Since I needed to send multiple properties to a method, I would use the Thread class and pass in a lambda expression.   Everything seem to be working fine, but I saw some strange things going on;  duplicate data was being sent to web service, even though the queue did not include duplicate data.  After a bit of debugging, I noticed that my call with the Lambda expression was passing the same data.  I did a little research on this issue and found this document, Closing over the loop variable considered harmful.   There’s a lot of technical info at this link, so I thought I would create a more simple example that would demonstrate this issue.

In this example I create a list of numbers and display these numbers to the console.  There are two individual foreach statements that loops through the numbers.   The first foreach does nothing special; it just calls DoWork.  All DoWork does is accepts an int and displays the number in the console.  Also DoWork has a sleep method to simulate a long running process.

The second foreach also calls DoWork, but calls DoWork on a separate thread.  The thread that is created accepts a Lambda, which points to DoWork.  It seems everything should work fine, but when you look at the results for the second foreach the data does not look correct.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Lambda_Threading
{
    class Program
    {
        static void Main(string[] args)
        {
            List numbers = GetData();

            foreach (int number in numbers)
            {
                DoWork(number);
            }

            Console.WriteLine("");
            Console.WriteLine("*****************************************");
            foreach (int number in numbers)
            {
                Thread thread = new Thread(() => DoWork(number));
                thread.Start();
            }

            Console.ReadLine();
        }

        public static void DoWork(int number)
        {
            Random rand = new Random();
            Thread.Sleep(rand.Next(200, 500)); //Simulate Work
            Console.Write(number + ", ");
        }

    
        public static List GetData()
        {
            List numbers = new List();

            for (int i = 0; i < 10; i++)
            {
                numbers.Add(i);
            }

            return numbers;
        }
    }
}

As you can see the results of the second foreach is not correct. The same number is displayed multiple time.  For example 9 is displayed three times and the numbers 0, 1, 2, 5, and 7 is not displayed at all.  The numbers are not in order because of the random sleep time in the DoWork method.

LamdaThreading

To solve this problem, all that is needed is a temp variable to store the number from the for loop.

foreach (int number in numbers)
{
    int tempNumber = number;
    Thread thread = new Thread(() => DoWork(tempNumber));
    thread.Start();
}

Now the results are what I was expecting.  The second foreach includes each number once and there are no duplicate numbers.  Again, the numbers are not in order because of the random sleep time in the DoWork method.  Even if you remove the sleep, the numbers still may not be in order.

LamdaThreadingTempVariable

Resources:

Simple Example – AOP – Policy Injection with Unity

This is just a simple example explaining the processes/patterns to implement them using Unity 2.0, Dependency Inject, Inversion of Control (Ioc), and Aspect Oriented Programming (AoP). One of my primary goals is to not over complicate these examples. The examples should show how to do one thing and one thing only, but could possibly show how to implement these process/patterns in multiple way.

In this entry I will create a very simple application that shows how to do dependency injection, Interception and Policy Injection using Unity 2.0.

I’m using Unity 2.0 which is part of Enterprise Framework 5.0, and have created a very simple example application to test implementing AOP through Unity Interception. I’ve read a few articles on the web of how to use Unity with Interception and Policy Injection, and believe the articles from Dino Espisto were very benefical in help me figure this stuff out.
MSDN – Aspect-Oriented Programming, Interception and Unity 2.0
MSDN – Interceptors in Unity
MSDN – Policy Injection in Unity

If you are not aware of AOP, one of the primis is that Cross Cutting functionality, such as Loggin, should not be included in your domain classes.  My example contains a very simple console application that inlcudes using Interception that is configured through the Fluent API and a Configuration file.  The example also shows how to do Policy Injection and also configured using Fluent API and Configuration file.

For a contrived rule, emails should not be sent where the email address ends with “@Test.com”.  I have a class called EmailSerivce.  The EmailService is a fake, it doesn’t do anything other then sleep and print a message to the console.   I do not want to add any code to the EmailSerivce class that validates email; this should be handel by Unity Policy Injection.
Continue reading “Simple Example – AOP – Policy Injection with Unity”