Ily*_*gin 2 c# linq lambda multithreading
我正在尝试在我的应用程序中实现任务.
这是示例代码:
有一个简单的接口我,3个类派生它(A,B,C)我创建一个Is的列表,用A,B,C实例poplualte,然后为对方创建一个任务来调用方法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();
}
}
Run Code Online (Sandbox Code Playgroud)
我期待着看到
A
B
C
Run Code Online (Sandbox Code Playgroud)
在输出中,而不是我得到的
C
C
C
Run Code Online (Sandbox Code Playgroud)
我在调试器中找到了问题:所有任务都有相同的委托,但我不知道为什么以及如何解决这个问题.
这是一个非常常见的问题.它涉及"捕获的变量"如何工作; 简短版本,你需要这个:
foreach (var i in l)
{
var copy = i;
Task task = new Task( () => copy.do1());
TaskPool.Add(task);
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是i(来自foreach)在技术上声明在循环范围之外,因此在该外部范围被捕获; 每次捕获相同的变量(C#捕获变量,而不是*值).copy 在循环范围内添加会改变这一点; 因为范围,每次迭代都会copy单独捕获.
问题是您i在分配委托时捕获循环变量.如果在分配之前创建临时副本,则可以避免捕获变量,从而获得所需的值.
foreach (var i in l)
{
var local = i;
Task task = new Task( () => local.do1());
TaskPool.Add(task);
}
Run Code Online (Sandbox Code Playgroud)