static void Main(string[] args)
{
Task[] tasks = new Task[10];
int[] numbers = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = Task.Run(() =>
{
Console.WriteLine("Number:{0}", numbers[i]); // 索引超出了数组界限。i会一直是10
});
}
Console.ReadLine();
}
原因解析:
Task.Run是在新的线程中异步执行的,在 for 循环中 Task 并不会立即执行,“i会一直是10”说明 for 循环结束后,Task 才开始执行,这时 i 的值正好是 10 。
解决办法:
这说明 i 的值没有被捕获到 Task 的执行上下文中,也就是说 i 变量的值不在捕获范围内,要想让 i 被捕获,需要引入中间变量,下面的代码就可以正常执行
static void Main(string[] args)
{
Task[] tasks = new Task[10];
int[] numbers = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < tasks.Length; i++)
{
int number = numbers[i];
tasks[i] = Task.Run(() =>
{
Console.WriteLine("Number:{0}", number); //这样就正常
});
}
Console.ReadLine();
}