I am trying to understand why this program doesn't work
Expected output: numbers 0-19 in random order What I get when I run: some numbers repeat, sometimes 20 is printed.
Please help. I tried with lock(obj) in DoSomething() but it didn't help.
Program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication2
{
public delegate void callbackDelegate(int x);
class Program
{
void processCallback(int x)
{
Console.WriteLine("IN callback: The value I got is " + x);
}
static void Main(string[] args)
{
Program p = new Program();
p.processinThreads();
Console.ReadKey();
}
public void DoSomething(int x, callbackDelegate callback)
{
Thread.Sleep(1000);
//Console.WriteLine("I just woke up now " + x);
callback(x);
}
public void processinThreads()
{
for (int i = 0; i < 20; i++)
{
Thread t =
new Thread(new ThreadStart(()=>DoSomething(i, processCallback)));
t.Start();
}
}
}
}
As Jakub already told you, you need to copy
i
into another local variablelocal
. In your code, the Delegates have direct access toi
itself, not a copy ofi
, so they print out the very current value ofi
, which may be greater than when you started the thread. This is called closure.You should just use the TPL, its a lot easier and recommended over manual thread management:
This will also block until the loop finishes, if you don't want that you can use the TPL
Task
, but I would definitely recommend avoiding threads.Your problem is related to closure over lambda.