问题
What I'm trying to do is very simple,
I scan a list of strings, then, I pass each string to a new thread for printing.
using System;
using System.Collections.Generic;
using System.Threading;
namespace MultithreadingSynchronization
{
class Program
{
static void Main(string[] args)
{
List<string> stringList = new List<string> { "server1", "server2", "server3", "server4", "server5", "server6", "server7", "server8", "server9"};
foreach (string server in stringList)
{
ThreadStart work = delegate { Threadjob(server); };
new Thread(work).Start();
//Thread.Sleep(10); // 10 ms delay of main thread
}
}
public static void Threadjob(object server)
{
Console.WriteLine(server);
}
}
}
From some reason, there are threads that received wrong value, therefore, the output presents some duplicated strings, and also miss some strings.
I'm expecting for this output (the order isn't important):
server1
server2
server3
server4
server5
server6
server7
server8
server9
But, sometimes I get this:
server3
server2
server5
server5
server7
server4
server8
server9
server9
and sometimes I get this:
server2
server2
server4
server3
server6
server7
server7
server8
server9
etc.
indeed, if I put a delay after each thread creating, I get what I expect to get.
Any idea?
回答1:
You should make local copy of variable. Try this:
foreach (string server in stringList)
{
string local = server;
ThreadStart work = delegate { Threadjob(local); };
new Thread(work).Start();
//Thread.Sleep(10); // 10 ms delay of main thread
}
More info here: Captured variable in a loop in C#
回答2:
new Thread(Threadjob).Start(server);
Done! However, it may be more advisable to use tasks rather than threads - or at least ThreadPool.
回答3:
OK, I think I get it.
Froeach loop hold a pointer, and changes it on each iteration.
Sometimes, the thread is created, but still not running.
meanwhile, the loop changes the pointer at the following iteration, and when the thread starts its job, it get the current pointer's value (the subsequent string).
BTW, I found another solution here, how to pass parameters to main function of the thread, so I fixed my loop and it works properly now
foreach (string server in stringList)
{
Thread thread1 = new Thread(new ParameterizedThreadStart(Threadjob));
thread1.Start(server);
}
来源:https://stackoverflow.com/questions/20503837/pass-each-list-item-to-a-new-thread-one-by-one