C#——多线程之异步调用容易出现的问题
- Q1:For中异步调用函数且函数输入具有实时性
Q1:For中异步调用函数且函数输入具有实时性
在项目进行过程中,发现For中用异步调用带有输入参数的函数时,会由于闭包特性,以及Task.Run的计划启动特性,导致输入会出现问题。
问题代码如下:
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
Task.Run(() =>
{
writeSth(i);
});
}
Console.ReadKey();
}
public static void writeSth(int index)
{
Console.WriteLine(index);
}
}
测试结果如下:
可以很明显的看出,由于异步启动存在延时,for又会因为异步task而不停的循环导致i的迅速递增。而当任务启动函数时,i并不是想要实现的数(理想的0-99打印)。
解决方案:
导致这一现象的原因是For的闭包特性,所以在调用前进行值的拷贝就可以了。代码如下:
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
int index = i;
Task.Run(() =>
{
writeSth(index);
});
}
Console.ReadKey();
}
public static void writeSth(int index)
{
Console.WriteLine(index);
}
}
测试结果如下:
PS:可以看出,Task.Run的执行是无序的,并不按照生成的先后执行。