I’m trying to implement Tasks in my Application.
Here’s the sample code:
There’s one simple Interface I, 3 classes are derived form it (A,B,C)
I create a list of Is, poplualte it with A, B, C instances, and then create a task for each other to call method do1();
interface I
{
void do1();
}
class A : I
{
public void do1()
{
Console.WriteLine("A");
}
}
class B : I
{
public void do1()
{
Console.WriteLine("B");
}
}
class C : I
{
public void do1()
{
Console.WriteLine("C");
}
}
class Program
{
public static void Main(string[] args)
{
List<I> l = new List<I>();
l.Add(new A());
l.Add(new B());
l.Add(new C());
var TaskPool = new List<Task>();
foreach (var i in l)
{
Task task = new Task( () => i.do1()
);
TaskPool.Add(task);
}
foreach (var c in TaskPool)
{
c.Start();
}
Thread.Sleep(3000);
Console.Read();
}
}
I’m expecting to see
A
B
C
In the output, but instead of it I get
C
C
C
I kinda found the problem in debugger: All tasks have the same delegate, but I do not know why and how to workaround this.
This is a very common question. It relates to how “captured variables” work; short version, you need this:
The problem here is that
i(from theforeach) is technically declared outside the scope of the loop, and thus is captured at that outer scope; you capture the same variable each time (C# captures variables, not *values). Addingcopyinside the loop-scope changes this; because of the scope,copyis captured separately per iteration.