Threads receiving wrong parameters

I need to run a method with a given parameter in a thread. I've noticed that when I run it, the parameter is wrong. For the example given, I have an array int[] output with the numbers 1-7. For each number, I create a thread with the method WriteInt(i). I expect the output to be 1-7 in any order, but I consistently see some numbers missed and others duplicated. What is going on and what would the correct way be to start these threads?

(The list is only there to join the threads afterwards)

class Program
{
    static void Main(string[] args)
    {
        int[] output = { 1, 2, 3, 4, 5, 6, 7 };

        List<Thread> runningThreads = new List<Thread>();

        foreach (int i in output)
        {
            Thread thread = new Thread(() => WriteInt(i));
            thread.Start();
            runningThreads.Add(thread);
        }
        foreach(Thread t in runningThreads)
        {
            t.Join();
        }
    }

    private static void WriteInt(int i)
    {
        Console.WriteLine(i);
    }
}

Example output:

3
3
4
5
6
7

Answers


The closure created by the lambda (() => WriteInt(i)) is getting closing over the variable i, not the value set to i within each iteration. As the thread runs, it uses the value set within i at that point in time, which is likely already been changed due to the foreach loop processing.

You need a temporary:

foreach (int i in output)
{
        int temp = i;
        Thread thread = new Thread(() => WriteInt(temp));
        thread.Start();
        runningThreads.Add(thread);
}

For details on what's happening, see Eric Lippert's post titled Closing over the loop variable considered harmful.

Also, in C# 5 (VS2012), this is no longer an issue for foreach loops. It will still happen with a for loop, however.


Need Your Help

EC2 Instance Cloning

amazon-ec2 amazon-web-services

Is it possible to clone a EC2 instance data and all?

PHP - Tree of Array References, first append to a new array is lost

php arrays tree reference

I have a tree structure composed of nested associative arrays. I have a set of paths that I want to add to the tree, where each element in the path is the name of a node. The code below should crea...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.