I think a better solution to this problem would be to use Parallel.ForEach
.
static void Main( string[ ] _ )
{
var list = new List<string> { "Value1", "Value2", "Value3" };
Parallel.ForEach( list, value => Method2( value ) );
}
Here is another solution using Task
's (setting and forgetting).
static void Main( string[ ] _ )
{
var list = new List<string> { "Value1", "Value2", "Value3" };
for ( int i = 0; i < list.Count; i++ )
{
var index = i;
// Set and forget.
Task.Run( ( ) => Method2( list[ index ] ) );
}
}
And here is another solution using Task
's but this time you await
for each of the Task
's to complete.
static async Task Main( string[ ] _ )
{
var list = new List<string> { "Value1", "Value2", "Value3" };
var tasks = new List<Task>( list.Count );
for ( int i = 0; i < list.Count; i++ )
{
var index = i;
// Set and forget.
tasks.Add( Task.Run( ( ) => Method2( list[ index ] ) ) );
}
await Task.WhenAll( tasks );
}
If you don't like that and want to stick with your solution then you can capture the i
variable locally in the for
loop.
for ( int i = 0; i < list.Count; i++ )
{
var index = i;
new Thread( ( ) => Method2( list[ index ] ) ).Start( );
}
Each Thread
will have its own copy of the index
variable, as opposed to each Thread
sharing a reference to the i
variable (which is what you're currently doing).
Your for
loop is finishing before the first Thread
has started; so when one of the Thread
's finally starts it sees the last value that i
was set to (in your case 3
).
If you don't believe me run the below code.
static void Main( string[ ] _ )
{
for ( int i = 0; i < 3; i++ )
{
new Thread( ( ) => Console.WriteLine( $"{i}" ) ).Start( );
Thread.Sleep( 1500 );
}
Console.ReadLine( );
}
You should see the values, 0
, 1
, 2
printed to the console.
Now, run this code (and note that I removed the Thread.Sleep
:
static void Main( string[ ] _ )
{
for ( int i = 0; i < 3; i++ )
{
new Thread( ( ) => Console.WriteLine( $"{i}" ) ).Start( );
}
Console.ReadLine( );
}
You should see the values, 3
, 3
, 3
printed to the console.