C# for循环给线程传迭代变量输出重复,不用Join如何并行输出0和1
问题原因
这是C#闭包捕获循环变量的典型问题:Lambda表达式捕获的是循环变量i的引用,而非每次迭代时i的瞬时值。线程启动需要时间,等到实际执行c1.pr(i)逻辑时,for循环已经执行完毕,此时i的最终值为2,所以两个线程输出的都是2。
解决方案
不需要使用Join()阻塞线程,只要在for循环内部声明一个局部临时变量,存储当前迭代的i值即可,修改后的Program.cs代码如下:
class Program { static void Main() { Class1 c1 = new Class1(); for(int i=0;i<2;i++) { // 每次迭代创建独立的局部变量,lambda捕获该次迭代独有的变量实例 int currentI = i; Thread t = new Thread(() => { c1.pr(currentI); }); t.Start(); } } }
原理说明
C#中for循环的循环变量是整个循环周期共享的,而循环内部声明的局部变量,每次迭代都会创建独立的新实例。lambda捕获每个迭代独有的局部变量后,就能拿到对应迭代的0、1值,同时所有线程可以并行执行,不会互相阻塞。
注意:受系统线程调度影响,最终输出的顺序可能是
0 1也可能是1 0,但值一定是0和1,不会出现2。如果需要严格保证输出顺序,才需要额外加同步控制逻辑。
内容的提问来源于stack exchange,提问作者Dat Cong Dinh
相关产品推荐
相关产品推荐

