This is my first question in this forum, so i hope to be clear:
I´m using Visual Studio 2010 RTM Programming in C#
The constructor of the class, which is converted to a thread, are always taking the values from the last Dictionary Entry.
I don´t know what i´m doing wrong, someone?
This Code doesn´t work:
Dictionary<string, Queue<string>> colas;
public DataDispatcher(Dictionary<string, int> lectoras, ReadEventHandler callback)
{
colas = new Dictionary<string, Queue<string>>();
foreach (KeyValuePair<string, int> pair in lectoras)
{
colas.Add(pair.Key, new Queue<string>>());
Thread hilo = new Thread(
() => new ReadHandler(pair.Value, colas[pair.Key], callback));
hilo.Name = "Hilo-" + hilo.ManagedThreadId.ToString();
hilo.Start();
}
}
Instead, this Code works perfectly:
Dictionary<string, Queue<string>> colas;
public DataDispatcher(Dictionary<string, int> lectoras, ReadEventHandler callback)
{
colas = new Dictionary<string, Queue<string>>();
foreach (KeyValuePair<string, int> pair in lectoras)
{
Queue<string> qs = new Queue<string>();
colas.Add(pair.Key, qs);
int jaula = pair.Value;
Thread hilo = new Thread(
() => new ReadHandler(jaula, qs, callback));
hilo.Name = "Hilo-" + hilo.ManagedThreadId.ToString();
hilo.Start();
}
}
It is a very common error called ‘capturing the loop variable’, or ‘closing over the variable’.
You were starting a number of threads all using the same variable
pair. This ‘captured’ variable behaves like a pass-by-reference parameter. By the time the Threads start executing theforeach()is done and they all use the last element.On a side note, you probably shouldn’t be using bare Threads for this. Use the ThreadPool or Task objects from the TPL.