Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create new threads in a for loop and pass parameters

Consider this code:

for(int i = 0; i < 10; i ++)
{
    new Thread(() => Test(i)).Start();
}

The Test(int i) function:

public void Test(int i)
{
    Console.WriteLine("=== Test " + i);
}

The actual output:

=== Test 3
=== Test 4
=== Test 4
=== Test 5
=== Test 5
=== Test 5
=== Test 9
=== Test 9
=== Test 9
=== Test 10

as you can see some numbers are missing and some other been duplicated.

Expected output:

I expect to see all numbers in random order.

Question

Should I lock any variables/methods? How can I fix this?

like image 663
A-Sharabiani Avatar asked Dec 24 '22 15:12

A-Sharabiani


2 Answers

Should I lock any variables/methods? How can I fix this?

Your problem is with Closure and Captured Variables

Change your code as

for(int i = 0; i < 10; i ++)
{
    int tmp = i;
    new Thread(() => Test(tmp)).Start();
}

For more info: http://csharpindepth.com/articles/chapter5/closures.aspx or http://geekswithblogs.net/rajeevr/archive/2012/02/26/closures-and-captured-variable.aspx

like image 61
Eser Avatar answered Feb 03 '23 16:02

Eser


There's an overload of the Thread.Start method that takes a parameter. Using that, you avoid the closure:

for(int i = 0; i < 10; i ++)
{
    new Thread(o => Test((int)o)).Start(i);
}
like image 25
Paulo Morgado Avatar answered Feb 03 '23 16:02

Paulo Morgado